net: wireless: rockchip_wlan: add rtl8188eu support
[firefly-linux-kernel-4.4.55.git] / drivers / net / wireless / rockchip_wlan / rtl8188eu / 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(%zu)\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(%zu)\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, size_t 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, const 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 inline void _rtw_memmove(void *dst, const void *src, u32 sz)
825 {
826 #if defined(PLATFORM_LINUX)
827         memmove(dst, src, sz);
828 #else
829         #warning "no implementation\n"
830 #endif
831 }
832
833 int     _rtw_memcmp(void *dst, const void *src, u32 sz)
834 {
835
836 #if defined (PLATFORM_LINUX)|| defined (PLATFORM_FREEBSD)
837 //under Linux/GNU/GLibc, the return value of memcmp for two same mem. chunk is 0
838
839         if (!(memcmp(dst, src, sz)))
840                 return _TRUE;
841         else
842                 return _FALSE;
843 #endif
844
845
846 #ifdef PLATFORM_WINDOWS
847 //under Windows, the return value of NdisEqualMemory for two same mem. chunk is 1
848         
849         if (NdisEqualMemory (dst, src, sz))
850                 return _TRUE;
851         else
852                 return _FALSE;
853
854 #endif  
855         
856         
857         
858 }
859
860 void _rtw_memset(void *pbuf, int c, u32 sz)
861 {
862
863 #if defined (PLATFORM_LINUX)|| defined (PLATFORM_FREEBSD)
864
865         memset(pbuf, c, sz);
866
867 #endif
868
869 #ifdef PLATFORM_WINDOWS
870 #if 0
871         NdisZeroMemory(pbuf, sz);
872         if (c != 0) memset(pbuf, c, sz);
873 #else
874         NdisFillMemory(pbuf, sz, c);
875 #endif
876 #endif
877
878 }
879
880 #ifdef PLATFORM_FREEBSD
881 static inline void __list_add(_list *pnew, _list *pprev, _list *pnext)
882  {
883          pnext->prev = pnew;
884          pnew->next = pnext;
885          pnew->prev = pprev;
886          pprev->next = pnew;
887 }
888 #endif /* PLATFORM_FREEBSD */
889
890
891 void _rtw_init_listhead(_list *list)
892 {
893
894 #ifdef PLATFORM_LINUX
895
896         INIT_LIST_HEAD(list);
897
898 #endif
899
900 #ifdef PLATFORM_FREEBSD
901          list->next = list;
902          list->prev = list;
903 #endif
904 #ifdef PLATFORM_WINDOWS
905
906         NdisInitializeListHead(list);
907
908 #endif
909
910 }
911
912
913 /*
914 For the following list_xxx operations, 
915 caller must guarantee the atomic context.
916 Otherwise, there will be racing condition.
917 */
918 u32     rtw_is_list_empty(_list *phead)
919 {
920
921 #ifdef PLATFORM_LINUX
922
923         if (list_empty(phead))
924                 return _TRUE;
925         else
926                 return _FALSE;
927
928 #endif
929 #ifdef PLATFORM_FREEBSD
930
931         if (phead->next == phead)
932                 return _TRUE;
933         else
934                 return _FALSE;
935
936 #endif
937
938
939 #ifdef PLATFORM_WINDOWS
940
941         if (IsListEmpty(phead))
942                 return _TRUE;
943         else
944                 return _FALSE;
945
946 #endif
947
948         
949 }
950
951 void rtw_list_insert_head(_list *plist, _list *phead)
952 {
953
954 #ifdef PLATFORM_LINUX
955         list_add(plist, phead);
956 #endif
957
958 #ifdef PLATFORM_FREEBSD
959         __list_add(plist, phead, phead->next);
960 #endif
961
962 #ifdef PLATFORM_WINDOWS
963         InsertHeadList(phead, plist);
964 #endif
965 }
966
967 void rtw_list_insert_tail(_list *plist, _list *phead)
968 {
969
970 #ifdef PLATFORM_LINUX   
971         
972         list_add_tail(plist, phead);
973         
974 #endif
975 #ifdef PLATFORM_FREEBSD
976         
977         __list_add(plist, phead->prev, phead);
978         
979 #endif  
980 #ifdef PLATFORM_WINDOWS
981
982   InsertTailList(phead, plist);
983
984 #endif          
985         
986 }
987
988 void rtw_init_timer(_timer *ptimer, void *padapter, void *pfunc)
989 {
990         _adapter *adapter = (_adapter *)padapter;       
991
992 #ifdef PLATFORM_LINUX
993         _init_timer(ptimer, adapter->pnetdev, pfunc, adapter);
994 #endif
995 #ifdef PLATFORM_FREEBSD
996         _init_timer(ptimer, adapter->pifp, pfunc, adapter->mlmepriv.nic_hdl);
997 #endif
998 #ifdef PLATFORM_WINDOWS
999         _init_timer(ptimer, adapter->hndis_adapter, pfunc, adapter->mlmepriv.nic_hdl);
1000 #endif
1001 }
1002
1003 /*
1004
1005 Caller must check if the list is empty before calling rtw_list_delete
1006
1007 */
1008
1009
1010 void _rtw_init_sema(_sema       *sema, int init_val)
1011 {
1012
1013 #ifdef PLATFORM_LINUX
1014
1015         sema_init(sema, init_val);
1016
1017 #endif
1018 #ifdef PLATFORM_FREEBSD
1019         sema_init(sema, init_val, "rtw_drv");
1020 #endif
1021 #ifdef PLATFORM_OS_XP
1022
1023         KeInitializeSemaphore(sema, init_val,  SEMA_UPBND); // count=0;
1024
1025 #endif
1026         
1027 #ifdef PLATFORM_OS_CE
1028         if(*sema == NULL)
1029                 *sema = CreateSemaphore(NULL, init_val, SEMA_UPBND, NULL);
1030 #endif
1031
1032 }
1033
1034 void _rtw_free_sema(_sema       *sema)
1035 {
1036 #ifdef PLATFORM_FREEBSD
1037         sema_destroy(sema);
1038 #endif
1039 #ifdef PLATFORM_OS_CE
1040         CloseHandle(*sema);
1041 #endif
1042
1043 }
1044
1045 void _rtw_up_sema(_sema *sema)
1046 {
1047
1048 #ifdef PLATFORM_LINUX
1049
1050         up(sema);
1051
1052 #endif  
1053 #ifdef PLATFORM_FREEBSD
1054         sema_post(sema);
1055 #endif
1056 #ifdef PLATFORM_OS_XP
1057
1058         KeReleaseSemaphore(sema, IO_NETWORK_INCREMENT, 1,  FALSE );
1059
1060 #endif
1061
1062 #ifdef PLATFORM_OS_CE
1063         ReleaseSemaphore(*sema,  1,  NULL );
1064 #endif
1065 }
1066
1067 u32 _rtw_down_sema(_sema *sema)
1068 {
1069
1070 #ifdef PLATFORM_LINUX
1071         
1072         if (down_interruptible(sema))
1073                 return _FAIL;
1074         else
1075                 return _SUCCESS;
1076
1077 #endif          
1078 #ifdef PLATFORM_FREEBSD
1079         sema_wait(sema);
1080         return  _SUCCESS;
1081 #endif
1082 #ifdef PLATFORM_OS_XP
1083
1084         if(STATUS_SUCCESS == KeWaitForSingleObject(sema, Executive, KernelMode, TRUE, NULL))
1085                 return  _SUCCESS;
1086         else
1087                 return _FAIL;
1088 #endif
1089
1090 #ifdef PLATFORM_OS_CE
1091         if(WAIT_OBJECT_0 == WaitForSingleObject(*sema, INFINITE ))
1092                 return _SUCCESS; 
1093         else
1094                 return _FAIL;
1095 #endif
1096 }
1097
1098
1099
1100 void    _rtw_mutex_init(_mutex *pmutex)
1101 {
1102 #ifdef PLATFORM_LINUX
1103
1104 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37))
1105         mutex_init(pmutex);
1106 #else
1107         init_MUTEX(pmutex);
1108 #endif
1109
1110 #endif
1111 #ifdef PLATFORM_FREEBSD
1112         mtx_init(pmutex, "", NULL, MTX_DEF|MTX_RECURSE);
1113 #endif
1114 #ifdef PLATFORM_OS_XP
1115
1116         KeInitializeMutex(pmutex, 0);
1117
1118 #endif
1119
1120 #ifdef PLATFORM_OS_CE
1121         *pmutex =  CreateMutex( NULL, _FALSE, NULL);
1122 #endif
1123 }
1124
1125 void    _rtw_mutex_free(_mutex *pmutex);
1126 void    _rtw_mutex_free(_mutex *pmutex)
1127 {
1128 #ifdef PLATFORM_LINUX
1129
1130 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37))
1131         mutex_destroy(pmutex);
1132 #else   
1133 #endif
1134
1135 #ifdef PLATFORM_FREEBSD
1136         sema_destroy(pmutex);
1137 #endif
1138
1139 #endif
1140
1141 #ifdef PLATFORM_OS_XP
1142
1143 #endif
1144
1145 #ifdef PLATFORM_OS_CE
1146
1147 #endif
1148 }
1149
1150 void    _rtw_spinlock_init(_lock *plock)
1151 {
1152
1153 #ifdef PLATFORM_LINUX
1154
1155         spin_lock_init(plock);
1156
1157 #endif  
1158 #ifdef PLATFORM_FREEBSD
1159                 mtx_init(plock, "", NULL, MTX_DEF|MTX_RECURSE);
1160 #endif
1161 #ifdef PLATFORM_WINDOWS
1162
1163         NdisAllocateSpinLock(plock);
1164
1165 #endif
1166         
1167 }
1168
1169 void    _rtw_spinlock_free(_lock *plock)
1170 {
1171 #ifdef PLATFORM_FREEBSD
1172          mtx_destroy(plock);
1173 #endif
1174         
1175 #ifdef PLATFORM_WINDOWS
1176
1177         NdisFreeSpinLock(plock);
1178
1179 #endif
1180         
1181 }
1182 #ifdef PLATFORM_FREEBSD
1183 extern PADAPTER prtw_lock;
1184
1185 void rtw_mtx_lock(_lock *plock){
1186         if(prtw_lock){
1187                 mtx_lock(&prtw_lock->glock);
1188         }
1189         else{
1190                 printf("%s prtw_lock==NULL",__FUNCTION__);
1191         }
1192 }
1193 void rtw_mtx_unlock(_lock *plock){
1194         if(prtw_lock){
1195                 mtx_unlock(&prtw_lock->glock);
1196         }
1197         else{
1198                 printf("%s prtw_lock==NULL",__FUNCTION__);
1199         }
1200         
1201 }
1202 #endif //PLATFORM_FREEBSD
1203
1204
1205 void    _rtw_spinlock(_lock     *plock)
1206 {
1207
1208 #ifdef PLATFORM_LINUX
1209
1210         spin_lock(plock);
1211
1212 #endif
1213 #ifdef PLATFORM_FREEBSD
1214         mtx_lock(plock);
1215 #endif
1216 #ifdef PLATFORM_WINDOWS
1217
1218         NdisAcquireSpinLock(plock);
1219
1220 #endif
1221         
1222 }
1223
1224 void    _rtw_spinunlock(_lock *plock)
1225 {
1226
1227 #ifdef PLATFORM_LINUX
1228
1229         spin_unlock(plock);
1230
1231 #endif
1232 #ifdef PLATFORM_FREEBSD
1233         mtx_unlock(plock);
1234 #endif  
1235 #ifdef PLATFORM_WINDOWS
1236
1237         NdisReleaseSpinLock(plock);
1238
1239 #endif
1240 }
1241
1242
1243 void    _rtw_spinlock_ex(_lock  *plock)
1244 {
1245
1246 #ifdef PLATFORM_LINUX
1247
1248         spin_lock(plock);
1249
1250 #endif
1251 #ifdef PLATFORM_FREEBSD
1252         mtx_lock(plock);
1253 #endif  
1254 #ifdef PLATFORM_WINDOWS
1255
1256         NdisDprAcquireSpinLock(plock);
1257
1258 #endif
1259         
1260 }
1261
1262 void    _rtw_spinunlock_ex(_lock *plock)
1263 {
1264
1265 #ifdef PLATFORM_LINUX
1266
1267         spin_unlock(plock);
1268
1269 #endif
1270 #ifdef PLATFORM_FREEBSD
1271         mtx_unlock(plock);
1272 #endif  
1273 #ifdef PLATFORM_WINDOWS
1274
1275         NdisDprReleaseSpinLock(plock);
1276
1277 #endif
1278 }
1279
1280
1281
1282 void _rtw_init_queue(_queue *pqueue)
1283 {
1284         _rtw_init_listhead(&(pqueue->queue));
1285         _rtw_spinlock_init(&(pqueue->lock));
1286 }
1287
1288 void _rtw_deinit_queue(_queue *pqueue)
1289 {
1290         _rtw_spinlock_free(&(pqueue->lock));
1291 }
1292
1293 u32       _rtw_queue_empty(_queue       *pqueue)
1294 {
1295         return (rtw_is_list_empty(&(pqueue->queue)));
1296 }
1297
1298
1299 u32 rtw_end_of_queue_search(_list *head, _list *plist)
1300 {
1301         if (head == plist)
1302                 return _TRUE;
1303         else
1304                 return _FALSE;
1305 }
1306
1307
1308 u32     rtw_get_current_time(void)
1309 {
1310         
1311 #ifdef PLATFORM_LINUX
1312         return jiffies;
1313 #endif  
1314 #ifdef PLATFORM_FREEBSD
1315         struct timeval tvp;
1316         getmicrotime(&tvp);
1317         return tvp.tv_sec;
1318 #endif
1319 #ifdef PLATFORM_WINDOWS
1320         LARGE_INTEGER   SystemTime;
1321         NdisGetCurrentSystemTime(&SystemTime);
1322         return (u32)(SystemTime.LowPart);// count of 100-nanosecond intervals 
1323 #endif
1324 }
1325
1326 inline u32 rtw_systime_to_ms(u32 systime)
1327 {
1328 #ifdef PLATFORM_LINUX
1329         return systime * 1000 / HZ;
1330 #endif  
1331 #ifdef PLATFORM_FREEBSD
1332         return systime * 1000;
1333 #endif  
1334 #ifdef PLATFORM_WINDOWS
1335         return systime / 10000 ; 
1336 #endif
1337 }
1338
1339 inline u32 rtw_ms_to_systime(u32 ms)
1340 {
1341 #ifdef PLATFORM_LINUX
1342         return ms * HZ / 1000;
1343 #endif  
1344 #ifdef PLATFORM_FREEBSD
1345         return ms /1000;
1346 #endif  
1347 #ifdef PLATFORM_WINDOWS
1348         return ms * 10000 ; 
1349 #endif
1350 }
1351
1352 // the input parameter start use the same unit as returned by rtw_get_current_time
1353 inline s32 rtw_get_passing_time_ms(u32 start)
1354 {
1355 #ifdef PLATFORM_LINUX
1356         return rtw_systime_to_ms(jiffies-start);
1357 #endif
1358 #ifdef PLATFORM_FREEBSD
1359         return rtw_systime_to_ms(rtw_get_current_time());
1360 #endif  
1361 #ifdef PLATFORM_WINDOWS
1362         LARGE_INTEGER   SystemTime;
1363         NdisGetCurrentSystemTime(&SystemTime);
1364         return rtw_systime_to_ms((u32)(SystemTime.LowPart) - start) ;
1365 #endif
1366 }
1367
1368 inline s32 rtw_get_time_interval_ms(u32 start, u32 end)
1369 {
1370 #ifdef PLATFORM_LINUX
1371         return rtw_systime_to_ms(end-start);
1372 #endif
1373 #ifdef PLATFORM_FREEBSD
1374         return rtw_systime_to_ms(rtw_get_current_time());
1375 #endif  
1376 #ifdef PLATFORM_WINDOWS
1377         return rtw_systime_to_ms(end-start);
1378 #endif
1379 }
1380         
1381
1382 void rtw_sleep_schedulable(int ms)      
1383 {
1384
1385 #ifdef PLATFORM_LINUX
1386
1387     u32 delta;
1388     
1389     delta = (ms * HZ)/1000;//(ms)
1390     if (delta == 0) {
1391         delta = 1;// 1 ms
1392     }
1393     set_current_state(TASK_INTERRUPTIBLE);
1394     if (schedule_timeout(delta) != 0) {
1395         return ;
1396     }
1397     return;
1398
1399 #endif  
1400 #ifdef PLATFORM_FREEBSD
1401         DELAY(ms*1000);
1402         return ;
1403 #endif  
1404         
1405 #ifdef PLATFORM_WINDOWS
1406
1407         NdisMSleep(ms*1000); //(us)*1000=(ms)
1408
1409 #endif
1410
1411 }
1412
1413
1414 void rtw_msleep_os(int ms)
1415 {
1416
1417 #ifdef PLATFORM_LINUX
1418         #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 36))
1419         if (ms < 20) {
1420                 unsigned long us = ms * 1000UL;
1421                 usleep_range(us, us + 1000UL);
1422         } else
1423         #endif
1424         msleep((unsigned int)ms);
1425
1426 #endif  
1427 #ifdef PLATFORM_FREEBSD
1428        //Delay for delay microseconds 
1429         DELAY(ms*1000);
1430         return ;
1431 #endif  
1432 #ifdef PLATFORM_WINDOWS
1433
1434         NdisMSleep(ms*1000); //(us)*1000=(ms)
1435
1436 #endif
1437
1438
1439 }
1440 void rtw_usleep_os(int us)
1441 {
1442 #ifdef PLATFORM_LINUX
1443
1444         // msleep((unsigned int)us);
1445         #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 36))
1446         usleep_range(us, us + 1);       
1447         #else
1448         if ( 1 < (us/1000) )
1449                 msleep(1);
1450       else
1451                 msleep( (us/1000) + 1);
1452         #endif
1453 #endif
1454
1455 #ifdef PLATFORM_FREEBSD
1456         //Delay for delay microseconds 
1457         DELAY(us);
1458
1459         return ;
1460 #endif  
1461 #ifdef PLATFORM_WINDOWS
1462
1463         NdisMSleep(us); //(us)
1464
1465 #endif
1466
1467
1468 }
1469
1470
1471 #ifdef DBG_DELAY_OS
1472 void _rtw_mdelay_os(int ms, const char *func, const int line)
1473 {
1474         #if 0
1475         if(ms>10)
1476                 DBG_871X("%s:%d %s(%d)\n", func, line, __FUNCTION__, ms);
1477                 rtw_msleep_os(ms);
1478         return;
1479         #endif
1480
1481
1482         DBG_871X("%s:%d %s(%d)\n", func, line, __FUNCTION__, ms);
1483
1484 #if defined(PLATFORM_LINUX)
1485
1486         mdelay((unsigned long)ms); 
1487
1488 #elif defined(PLATFORM_WINDOWS)
1489
1490         NdisStallExecution(ms*1000); //(us)*1000=(ms)
1491
1492 #endif
1493
1494
1495 }
1496 void _rtw_udelay_os(int us, const char *func, const int line)
1497 {
1498
1499         #if 0
1500         if(us > 1000) {
1501         DBG_871X("%s:%d %s(%d)\n", func, line, __FUNCTION__, us);
1502                 rtw_usleep_os(us);
1503                 return;
1504         }
1505         #endif 
1506
1507
1508         DBG_871X("%s:%d %s(%d)\n", func, line, __FUNCTION__, us);
1509         
1510         
1511 #if defined(PLATFORM_LINUX)
1512
1513       udelay((unsigned long)us); 
1514
1515 #elif defined(PLATFORM_WINDOWS)
1516
1517         NdisStallExecution(us); //(us)
1518
1519 #endif
1520
1521 }
1522 #else
1523 void rtw_mdelay_os(int ms)
1524 {
1525
1526 #ifdef PLATFORM_LINUX
1527
1528         mdelay((unsigned long)ms); 
1529
1530 #endif  
1531 #ifdef PLATFORM_FREEBSD
1532         DELAY(ms*1000);
1533         return ;
1534 #endif  
1535 #ifdef PLATFORM_WINDOWS
1536
1537         NdisStallExecution(ms*1000); //(us)*1000=(ms)
1538
1539 #endif
1540
1541
1542 }
1543 void rtw_udelay_os(int us)
1544 {
1545
1546 #ifdef PLATFORM_LINUX
1547
1548       udelay((unsigned long)us); 
1549
1550 #endif  
1551 #ifdef PLATFORM_FREEBSD
1552         //Delay for delay microseconds 
1553         DELAY(us);
1554         return ;
1555 #endif          
1556 #ifdef PLATFORM_WINDOWS
1557
1558         NdisStallExecution(us); //(us)
1559
1560 #endif
1561
1562 }
1563 #endif
1564
1565 void rtw_yield_os(void)
1566 {
1567 #ifdef PLATFORM_LINUX
1568         yield();
1569 #endif
1570 #ifdef PLATFORM_FREEBSD
1571         yield();
1572 #endif
1573 #ifdef PLATFORM_WINDOWS
1574         SwitchToThread();
1575 #endif
1576 }
1577
1578 #define RTW_SUSPEND_LOCK_NAME "rtw_wifi"
1579 #define RTW_SUSPEND_EXT_LOCK_NAME "rtw_wifi_ext"
1580 #define RTW_SUSPEND_RX_LOCK_NAME "rtw_wifi_rx"
1581 #define RTW_SUSPEND_TRAFFIC_LOCK_NAME "rtw_wifi_traffic"
1582 #define RTW_SUSPEND_RESUME_LOCK_NAME "rtw_wifi_resume"
1583 #define RTW_RESUME_SCAN_LOCK_NAME "rtw_wifi_scan"
1584 #ifdef CONFIG_WAKELOCK
1585 static struct wake_lock rtw_suspend_lock;
1586 static struct wake_lock rtw_suspend_ext_lock;
1587 static struct wake_lock rtw_suspend_rx_lock;
1588 static struct wake_lock rtw_suspend_traffic_lock;
1589 static struct wake_lock rtw_suspend_resume_lock;
1590 static struct wake_lock rtw_resume_scan_lock;
1591 #elif defined(CONFIG_ANDROID_POWER)
1592 static android_suspend_lock_t rtw_suspend_lock ={
1593         .name = RTW_SUSPEND_LOCK_NAME
1594 };
1595 static android_suspend_lock_t rtw_suspend_ext_lock ={
1596         .name = RTW_SUSPEND_EXT_LOCK_NAME
1597 };
1598 static android_suspend_lock_t rtw_suspend_rx_lock ={
1599         .name = RTW_SUSPEND_RX_LOCK_NAME
1600 };
1601 static android_suspend_lock_t rtw_suspend_traffic_lock ={
1602         .name = RTW_SUSPEND_TRAFFIC_LOCK_NAME
1603 };
1604 static android_suspend_lock_t rtw_suspend_resume_lock ={
1605         .name = RTW_SUSPEND_RESUME_LOCK_NAME
1606 };
1607 static android_suspend_lock_t rtw_resume_scan_lock ={
1608         .name = RTW_RESUME_SCAN_LOCK_NAME
1609 };
1610 #endif
1611
1612 inline void rtw_suspend_lock_init(void)
1613 {
1614         #ifdef CONFIG_WAKELOCK
1615         wake_lock_init(&rtw_suspend_lock, WAKE_LOCK_SUSPEND, RTW_SUSPEND_LOCK_NAME);
1616         wake_lock_init(&rtw_suspend_ext_lock, WAKE_LOCK_SUSPEND, RTW_SUSPEND_EXT_LOCK_NAME);
1617         wake_lock_init(&rtw_suspend_rx_lock, WAKE_LOCK_SUSPEND, RTW_SUSPEND_RX_LOCK_NAME);
1618         wake_lock_init(&rtw_suspend_traffic_lock, WAKE_LOCK_SUSPEND, RTW_SUSPEND_TRAFFIC_LOCK_NAME);
1619         wake_lock_init(&rtw_suspend_resume_lock, WAKE_LOCK_SUSPEND, RTW_SUSPEND_RESUME_LOCK_NAME);
1620         wake_lock_init(&rtw_resume_scan_lock, WAKE_LOCK_SUSPEND, RTW_RESUME_SCAN_LOCK_NAME);
1621         #elif defined(CONFIG_ANDROID_POWER)
1622         android_init_suspend_lock(&rtw_suspend_lock);
1623         android_init_suspend_lock(&rtw_suspend_ext_lock);
1624         android_init_suspend_lock(&rtw_suspend_rx_lock);
1625         android_init_suspend_lock(&rtw_suspend_traffic_lock);
1626         android_init_suspend_lock(&rtw_suspend_resume_lock);
1627         android_init_suspend_lock(&rtw_resume_scan_lock);
1628         #endif
1629 }
1630
1631 inline void rtw_suspend_lock_uninit(void)
1632 {
1633         #ifdef CONFIG_WAKELOCK
1634         wake_lock_destroy(&rtw_suspend_lock);
1635         wake_lock_destroy(&rtw_suspend_ext_lock);
1636         wake_lock_destroy(&rtw_suspend_rx_lock);
1637         wake_lock_destroy(&rtw_suspend_traffic_lock);
1638         wake_lock_destroy(&rtw_suspend_resume_lock);
1639         wake_lock_destroy(&rtw_resume_scan_lock);
1640         #elif defined(CONFIG_ANDROID_POWER)
1641         android_uninit_suspend_lock(&rtw_suspend_lock);
1642         android_uninit_suspend_lock(&rtw_suspend_ext_lock);
1643         android_uninit_suspend_lock(&rtw_suspend_rx_lock);
1644         android_uninit_suspend_lock(&rtw_suspend_traffic_lock);
1645         android_uninit_suspend_lock(&rtw_suspend_resume_lock);
1646         android_uninit_suspend_lock(&rtw_resume_scan_lock);
1647         #endif
1648 }
1649
1650 inline void rtw_lock_suspend(void)
1651 {
1652         #ifdef CONFIG_WAKELOCK
1653         wake_lock(&rtw_suspend_lock);
1654         #elif defined(CONFIG_ANDROID_POWER)
1655         android_lock_suspend(&rtw_suspend_lock);
1656         #endif
1657
1658         #if  defined(CONFIG_WAKELOCK) || defined(CONFIG_ANDROID_POWER)
1659         //DBG_871X("####%s: suspend_lock_count:%d####\n", __FUNCTION__, rtw_suspend_lock.stat.count);
1660         #endif
1661 }
1662
1663 inline void rtw_unlock_suspend(void)
1664 {
1665         #ifdef CONFIG_WAKELOCK
1666         wake_unlock(&rtw_suspend_lock);
1667         #elif defined(CONFIG_ANDROID_POWER)
1668         android_unlock_suspend(&rtw_suspend_lock);
1669         #endif
1670
1671         #if  defined(CONFIG_WAKELOCK) || defined(CONFIG_ANDROID_POWER)
1672         //DBG_871X("####%s: suspend_lock_count:%d####\n", __FUNCTION__, rtw_suspend_lock.stat.count);
1673         #endif
1674 }
1675
1676 inline void rtw_resume_lock_suspend(void)
1677 {
1678         #ifdef CONFIG_WAKELOCK
1679         wake_lock(&rtw_suspend_resume_lock);
1680         #elif defined(CONFIG_ANDROID_POWER)
1681         android_lock_suspend(&rtw_suspend_resume_lock);
1682         #endif
1683
1684         #if  defined(CONFIG_WAKELOCK) || defined(CONFIG_ANDROID_POWER)
1685         //DBG_871X("####%s: suspend_lock_count:%d####\n", __FUNCTION__, rtw_suspend_lock.stat.count);
1686         #endif
1687 }
1688
1689 inline void rtw_resume_unlock_suspend(void)
1690 {
1691         #ifdef CONFIG_WAKELOCK
1692         wake_unlock(&rtw_suspend_resume_lock);
1693         #elif defined(CONFIG_ANDROID_POWER)
1694         android_unlock_suspend(&rtw_suspend_resume_lock);
1695         #endif
1696
1697         #if  defined(CONFIG_WAKELOCK) || defined(CONFIG_ANDROID_POWER)
1698         //DBG_871X("####%s: suspend_lock_count:%d####\n", __FUNCTION__, rtw_suspend_lock.stat.count);
1699         #endif
1700 }
1701
1702 inline void rtw_lock_suspend_timeout(u32 timeout_ms)
1703 {
1704         #ifdef CONFIG_WAKELOCK
1705         wake_lock_timeout(&rtw_suspend_lock, rtw_ms_to_systime(timeout_ms));
1706         #elif defined(CONFIG_ANDROID_POWER)
1707         android_lock_suspend_auto_expire(&rtw_suspend_lock, rtw_ms_to_systime(timeout_ms));
1708         #endif
1709 }
1710
1711 inline void rtw_lock_ext_suspend_timeout(u32 timeout_ms)
1712 {
1713         #ifdef CONFIG_WAKELOCK
1714         wake_lock_timeout(&rtw_suspend_ext_lock, rtw_ms_to_systime(timeout_ms));
1715         #elif defined(CONFIG_ANDROID_POWER)
1716         android_lock_suspend_auto_expire(&rtw_suspend_ext_lock, rtw_ms_to_systime(timeout_ms));
1717         #endif
1718         //DBG_871X("EXT lock timeout:%d\n", timeout_ms);
1719 }
1720
1721 inline void rtw_lock_rx_suspend_timeout(u32 timeout_ms)
1722 {
1723         #ifdef CONFIG_WAKELOCK
1724         wake_lock_timeout(&rtw_suspend_rx_lock, rtw_ms_to_systime(timeout_ms));
1725         #elif defined(CONFIG_ANDROID_POWER)
1726         android_lock_suspend_auto_expire(&rtw_suspend_rx_lock, rtw_ms_to_systime(timeout_ms));
1727         #endif
1728         //DBG_871X("RX lock timeout:%d\n", timeout_ms);
1729 }
1730
1731
1732 inline void rtw_lock_traffic_suspend_timeout(u32 timeout_ms)
1733 {
1734         #ifdef CONFIG_WAKELOCK
1735         wake_lock_timeout(&rtw_suspend_traffic_lock, rtw_ms_to_systime(timeout_ms));
1736         #elif defined(CONFIG_ANDROID_POWER)
1737         android_lock_suspend_auto_expire(&rtw_suspend_traffic_lock, rtw_ms_to_systime(timeout_ms));
1738         #endif
1739         //DBG_871X("traffic lock timeout:%d\n", timeout_ms);
1740 }
1741
1742 inline void rtw_lock_resume_scan_timeout(u32 timeout_ms)
1743 {
1744         #ifdef CONFIG_WAKELOCK
1745         wake_lock_timeout(&rtw_resume_scan_lock, rtw_ms_to_systime(timeout_ms));
1746         #elif defined(CONFIG_ANDROID_POWER)
1747         android_lock_suspend_auto_expire(&rtw_resume_scan_lock, rtw_ms_to_systime(timeout_ms));
1748         #endif
1749         //DBG_871X("resume scan lock:%d\n", timeout_ms);
1750 }
1751
1752 inline void ATOMIC_SET(ATOMIC_T *v, int i)
1753 {
1754         #ifdef PLATFORM_LINUX
1755         atomic_set(v,i);
1756         #elif defined(PLATFORM_WINDOWS)
1757         *v=i;// other choice????
1758         #elif defined(PLATFORM_FREEBSD)
1759         atomic_set_int(v,i);
1760         #endif
1761 }
1762
1763 inline int ATOMIC_READ(ATOMIC_T *v)
1764 {
1765         #ifdef PLATFORM_LINUX
1766         return atomic_read(v);
1767         #elif defined(PLATFORM_WINDOWS)
1768         return *v; // other choice????
1769         #elif defined(PLATFORM_FREEBSD)
1770         return atomic_load_acq_32(v);
1771         #endif
1772 }
1773
1774 inline void ATOMIC_ADD(ATOMIC_T *v, int i)
1775 {
1776         #ifdef PLATFORM_LINUX
1777         atomic_add(i,v);
1778         #elif defined(PLATFORM_WINDOWS)
1779         InterlockedAdd(v,i);
1780         #elif defined(PLATFORM_FREEBSD)
1781         atomic_add_int(v,i);
1782         #endif
1783 }
1784 inline void ATOMIC_SUB(ATOMIC_T *v, int i)
1785 {
1786         #ifdef PLATFORM_LINUX
1787         atomic_sub(i,v);
1788         #elif defined(PLATFORM_WINDOWS)
1789         InterlockedAdd(v,-i);
1790         #elif defined(PLATFORM_FREEBSD)
1791         atomic_subtract_int(v,i);
1792         #endif
1793 }
1794
1795 inline void ATOMIC_INC(ATOMIC_T *v)
1796 {
1797         #ifdef PLATFORM_LINUX
1798         atomic_inc(v);
1799         #elif defined(PLATFORM_WINDOWS)
1800         InterlockedIncrement(v);
1801         #elif defined(PLATFORM_FREEBSD)
1802         atomic_add_int(v,1);
1803         #endif
1804 }
1805
1806 inline void ATOMIC_DEC(ATOMIC_T *v)
1807 {
1808         #ifdef PLATFORM_LINUX
1809         atomic_dec(v);
1810         #elif defined(PLATFORM_WINDOWS)
1811         InterlockedDecrement(v);
1812         #elif defined(PLATFORM_FREEBSD)
1813         atomic_subtract_int(v,1);
1814         #endif
1815 }
1816
1817 inline int ATOMIC_ADD_RETURN(ATOMIC_T *v, int i)
1818 {
1819         #ifdef PLATFORM_LINUX
1820         return atomic_add_return(i,v);
1821         #elif defined(PLATFORM_WINDOWS)
1822         return InterlockedAdd(v,i);
1823         #elif defined(PLATFORM_FREEBSD)
1824         atomic_add_int(v,i);
1825         return atomic_load_acq_32(v);
1826         #endif
1827 }
1828
1829 inline int ATOMIC_SUB_RETURN(ATOMIC_T *v, int i)
1830 {
1831         #ifdef PLATFORM_LINUX
1832         return atomic_sub_return(i,v);
1833         #elif defined(PLATFORM_WINDOWS)
1834         return InterlockedAdd(v,-i);
1835         #elif defined(PLATFORM_FREEBSD)
1836         atomic_subtract_int(v,i);
1837         return atomic_load_acq_32(v);
1838         #endif
1839 }
1840
1841 inline int ATOMIC_INC_RETURN(ATOMIC_T *v)
1842 {
1843         #ifdef PLATFORM_LINUX
1844         return atomic_inc_return(v);
1845         #elif defined(PLATFORM_WINDOWS)
1846         return InterlockedIncrement(v);
1847         #elif defined(PLATFORM_FREEBSD)
1848         atomic_add_int(v,1);
1849         return atomic_load_acq_32(v);
1850         #endif
1851 }
1852
1853 inline int ATOMIC_DEC_RETURN(ATOMIC_T *v)
1854 {
1855         #ifdef PLATFORM_LINUX
1856         return atomic_dec_return(v);
1857         #elif defined(PLATFORM_WINDOWS)
1858         return InterlockedDecrement(v);
1859         #elif defined(PLATFORM_FREEBSD)
1860         atomic_subtract_int(v,1);
1861         return atomic_load_acq_32(v);
1862         #endif
1863 }
1864
1865
1866 #ifdef PLATFORM_LINUX
1867 /*
1868 * Open a file with the specific @param path, @param flag, @param mode
1869 * @param fpp the pointer of struct file pointer to get struct file pointer while file opening is success
1870 * @param path the path of the file to open
1871 * @param flag file operation flags, please refer to linux document
1872 * @param mode please refer to linux document
1873 * @return Linux specific error code
1874 */
1875 static int openFile(struct file **fpp, char *path, int flag, int mode) 
1876
1877         struct file *fp; 
1878  
1879         fp=filp_open(path, flag, mode); 
1880         if(IS_ERR(fp)) {
1881                 *fpp=NULL;
1882                 return PTR_ERR(fp);
1883         }
1884         else {
1885                 *fpp=fp; 
1886                 return 0;
1887         }       
1888 }
1889
1890 /*
1891 * Close the file with the specific @param fp
1892 * @param fp the pointer of struct file to close
1893 * @return always 0
1894 */
1895 static int closeFile(struct file *fp) 
1896
1897         filp_close(fp,NULL);
1898         return 0; 
1899 }
1900
1901 static int readFile(struct file *fp,char *buf,int len) 
1902
1903         int rlen=0, sum=0;
1904         
1905         if (!fp->f_op || !fp->f_op->read) 
1906                 return -EPERM;
1907
1908         while(sum<len) {
1909                 rlen=fp->f_op->read(fp,buf+sum,len-sum, &fp->f_pos);
1910                 if(rlen>0)
1911                         sum+=rlen;
1912                 else if(0 != rlen)
1913                         return rlen;
1914                 else
1915                         break;
1916         }
1917         
1918         return  sum;
1919
1920 }
1921
1922 static int writeFile(struct file *fp,char *buf,int len) 
1923
1924         int wlen=0, sum=0;
1925         
1926         if (!fp->f_op || !fp->f_op->write) 
1927                 return -EPERM; 
1928
1929         while(sum<len) {
1930                 wlen=fp->f_op->write(fp,buf+sum,len-sum, &fp->f_pos);
1931                 if(wlen>0)
1932                         sum+=wlen;
1933                 else if(0 != wlen)
1934                         return wlen;
1935                 else
1936                         break;
1937         }
1938
1939         return sum;
1940
1941 }
1942
1943 /*
1944 * Test if the specifi @param path is a file and readable
1945 * @param path the path of the file to test
1946 * @return Linux specific error code
1947 */
1948 static int isFileReadable(char *path)
1949
1950         struct file *fp;
1951         int ret = 0;
1952         mm_segment_t oldfs;
1953         char buf;
1954  
1955         fp=filp_open(path, O_RDONLY, 0); 
1956         if(IS_ERR(fp)) {
1957                 ret = PTR_ERR(fp);
1958         }
1959         else {
1960                 oldfs = get_fs(); set_fs(get_ds());
1961                 
1962                 if(1!=readFile(fp, &buf, 1))
1963                         ret = PTR_ERR(fp);
1964                 
1965                 set_fs(oldfs);
1966                 filp_close(fp,NULL);
1967         }       
1968         return ret;
1969 }
1970
1971 /*
1972 * Open the file with @param path and retrive the file content into memory starting from @param buf for @param sz at most
1973 * @param path the path of the file to open and read
1974 * @param buf the starting address of the buffer to store file content
1975 * @param sz how many bytes to read at most
1976 * @return the byte we've read, or Linux specific error code
1977 */
1978 static int retriveFromFile(char *path, u8* buf, u32 sz)
1979 {
1980         int ret =-1;
1981         mm_segment_t oldfs;
1982         struct file *fp;
1983
1984         if(path && buf) {
1985                 if( 0 == (ret=openFile(&fp,path, O_RDONLY, 0)) ){
1986                         DBG_871X("%s openFile path:%s fp=%p\n",__FUNCTION__, path ,fp);
1987
1988                         oldfs = get_fs(); set_fs(get_ds());
1989                         ret=readFile(fp, buf, sz);
1990                         set_fs(oldfs);
1991                         closeFile(fp);
1992                         
1993                         DBG_871X("%s readFile, ret:%d\n",__FUNCTION__, ret);
1994                         
1995                 } else {
1996                         DBG_871X("%s openFile path:%s Fail, ret:%d\n",__FUNCTION__, path, ret);
1997                 }
1998         } else {
1999                 DBG_871X("%s NULL pointer\n",__FUNCTION__);
2000                 ret =  -EINVAL;
2001         }
2002         return ret;
2003 }
2004
2005 /*
2006 * Open the file with @param path and wirte @param sz byte of data starting from @param buf into the file
2007 * @param path the path of the file to open and write
2008 * @param buf the starting address of the data to write into file
2009 * @param sz how many bytes to write at most
2010 * @return the byte we've written, or Linux specific error code
2011 */
2012 static int storeToFile(char *path, u8* buf, u32 sz)
2013 {
2014         int ret =0;
2015         mm_segment_t oldfs;
2016         struct file *fp;
2017         
2018         if(path && buf) {
2019                 if( 0 == (ret=openFile(&fp, path, O_CREAT|O_WRONLY, 0666)) ) {
2020                         DBG_871X("%s openFile path:%s fp=%p\n",__FUNCTION__, path ,fp);
2021
2022                         oldfs = get_fs(); set_fs(get_ds());
2023                         ret=writeFile(fp, buf, sz);
2024                         set_fs(oldfs);
2025                         closeFile(fp);
2026
2027                         DBG_871X("%s writeFile, ret:%d\n",__FUNCTION__, ret);
2028                         
2029                 } else {
2030                         DBG_871X("%s openFile path:%s Fail, ret:%d\n",__FUNCTION__, path, ret);
2031                 }       
2032         } else {
2033                 DBG_871X("%s NULL pointer\n",__FUNCTION__);
2034                 ret =  -EINVAL;
2035         }
2036         return ret;
2037 }
2038 #endif //PLATFORM_LINUX
2039
2040 /*
2041 * Test if the specifi @param path is a file and readable
2042 * @param path the path of the file to test
2043 * @return _TRUE or _FALSE
2044 */
2045 int rtw_is_file_readable(char *path)
2046 {
2047 #ifdef PLATFORM_LINUX
2048         if(isFileReadable(path) == 0)
2049                 return _TRUE;
2050         else
2051                 return _FALSE;
2052 #else
2053         //Todo...
2054         return _FALSE;
2055 #endif
2056 }
2057
2058 /*
2059 * Open the file with @param path and retrive the file content into memory starting from @param buf for @param sz at most
2060 * @param path the path of the file to open and read
2061 * @param buf the starting address of the buffer to store file content
2062 * @param sz how many bytes to read at most
2063 * @return the byte we've read
2064 */
2065 int rtw_retrieve_from_file(char *path, u8 *buf, u32 sz)
2066 {
2067 #ifdef PLATFORM_LINUX
2068         int ret =retriveFromFile(path, buf, sz);
2069         return ret>=0?ret:0;
2070 #else
2071         //Todo...
2072         return 0;
2073 #endif
2074 }
2075
2076 /*
2077 * Open the file with @param path and wirte @param sz byte of data starting from @param buf into the file
2078 * @param path the path of the file to open and write
2079 * @param buf the starting address of the data to write into file
2080 * @param sz how many bytes to write at most
2081 * @return the byte we've written
2082 */
2083 int rtw_store_to_file(char *path, u8* buf, u32 sz)
2084 {
2085 #ifdef PLATFORM_LINUX
2086         int ret =storeToFile(path, buf, sz);
2087         return ret>=0?ret:0;
2088 #else
2089         //Todo...
2090         return 0;
2091 #endif
2092 }
2093
2094 #ifdef PLATFORM_LINUX
2095 struct net_device *rtw_alloc_etherdev_with_old_priv(int sizeof_priv, void *old_priv)
2096 {
2097         struct net_device *pnetdev;
2098         struct rtw_netdev_priv_indicator *pnpi;
2099
2100 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,35))
2101         pnetdev = alloc_etherdev_mq(sizeof(struct rtw_netdev_priv_indicator), 4);
2102 #else
2103         pnetdev = alloc_etherdev(sizeof(struct rtw_netdev_priv_indicator));
2104 #endif
2105         if (!pnetdev)
2106                 goto RETURN;
2107         
2108         pnpi = netdev_priv(pnetdev);
2109         pnpi->priv=old_priv;
2110         pnpi->sizeof_priv=sizeof_priv;
2111
2112 RETURN:
2113         return pnetdev;
2114 }
2115
2116 struct net_device *rtw_alloc_etherdev(int sizeof_priv)
2117 {
2118         struct net_device *pnetdev;
2119         struct rtw_netdev_priv_indicator *pnpi;
2120
2121 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,35))
2122         pnetdev = alloc_etherdev_mq(sizeof(struct rtw_netdev_priv_indicator), 4);
2123 #else
2124         pnetdev = alloc_etherdev(sizeof(struct rtw_netdev_priv_indicator));
2125 #endif
2126         if (!pnetdev)
2127                 goto RETURN;
2128         
2129         pnpi = netdev_priv(pnetdev);
2130         
2131         pnpi->priv = rtw_zvmalloc(sizeof_priv);
2132         if (!pnpi->priv) {
2133                 free_netdev(pnetdev);
2134                 pnetdev = NULL;
2135                 goto RETURN;
2136         }
2137         
2138         pnpi->sizeof_priv=sizeof_priv;
2139 RETURN:
2140         return pnetdev;
2141 }
2142
2143 void rtw_free_netdev(struct net_device * netdev)
2144 {
2145         struct rtw_netdev_priv_indicator *pnpi;
2146         
2147         if(!netdev)
2148                 goto RETURN;
2149         
2150         pnpi = netdev_priv(netdev);
2151
2152         if(!pnpi->priv)
2153                 goto RETURN;
2154
2155         free_netdev(netdev);
2156
2157 RETURN:
2158         return;
2159 }
2160
2161 /*
2162 * Jeff: this function should be called under ioctl (rtnl_lock is accquired) while 
2163 * LINUX_VERSION_CODE < KERNEL_VERSION(2,6,26)
2164 */
2165 int rtw_change_ifname(_adapter *padapter, const char *ifname)
2166 {
2167         struct net_device *pnetdev;
2168         struct net_device *cur_pnetdev;
2169         struct rereg_nd_name_data *rereg_priv;
2170         int ret;
2171
2172         if(!padapter)
2173                 goto error;
2174
2175         cur_pnetdev = padapter->pnetdev;
2176         rereg_priv = &padapter->rereg_nd_name_priv;
2177         
2178         //free the old_pnetdev
2179         if(rereg_priv->old_pnetdev) {
2180                 free_netdev(rereg_priv->old_pnetdev);
2181                 rereg_priv->old_pnetdev = NULL;
2182         }
2183
2184 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26))
2185         if(!rtnl_is_locked())
2186                 unregister_netdev(cur_pnetdev);
2187         else
2188 #endif
2189                 unregister_netdevice(cur_pnetdev);
2190
2191         rereg_priv->old_pnetdev=cur_pnetdev;
2192
2193         pnetdev = rtw_init_netdev(padapter);
2194         if (!pnetdev)  {
2195                 ret = -1;
2196                 goto error;
2197         }
2198
2199         SET_NETDEV_DEV(pnetdev, dvobj_to_dev(adapter_to_dvobj(padapter)));
2200
2201         rtw_init_netdev_name(pnetdev, ifname);
2202
2203         _rtw_memcpy(pnetdev->dev_addr, adapter_mac_addr(padapter), ETH_ALEN);
2204
2205 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26))
2206         if(!rtnl_is_locked())
2207                 ret = register_netdev(pnetdev);
2208         else
2209 #endif
2210                 ret = register_netdevice(pnetdev);
2211
2212         if ( ret != 0) {
2213                 RT_TRACE(_module_hci_intfs_c_,_drv_err_,("register_netdev() failed\n"));
2214                 goto error;
2215         }
2216
2217         return 0;
2218
2219 error:
2220         
2221         return -1;
2222         
2223 }
2224 #endif
2225
2226 #ifdef PLATFORM_FREEBSD
2227 /*
2228  * Copy a buffer from userspace and write into kernel address 
2229  * space.
2230  *
2231  * This emulation just calls the FreeBSD copyin function (to 
2232  * copy data from user space buffer into a kernel space buffer)
2233  * and is designed to be used with the above io_write_wrapper.
2234  *
2235  * This function should return the number of bytes not copied.
2236  * I.e. success results in a zero value. 
2237  * Negative error values are not returned.
2238  */
2239 unsigned long
2240 copy_from_user(void *to, const void *from, unsigned long n)
2241 {      
2242         if ( copyin(from, to, n) != 0 ) {
2243                 /* Any errors will be treated as a failure
2244                    to copy any of the requested bytes */
2245                 return n;
2246         }
2247
2248         return 0;
2249 }
2250
2251 unsigned long
2252 copy_to_user(void *to, const void *from, unsigned long n)
2253 {
2254         if ( copyout(from, to, n) != 0 ) {
2255                 /* Any errors will be treated as a failure
2256                    to copy any of the requested bytes */
2257                 return n;
2258         }
2259
2260         return 0;
2261 }
2262
2263
2264 /*
2265  * The usb_register and usb_deregister functions are used to register
2266  * usb drivers with the usb subsystem. In this compatibility layer
2267  * emulation a list of drivers (struct usb_driver) is maintained
2268  * and is used for probing/attaching etc.
2269  *
2270  * usb_register and usb_deregister simply call these functions.
2271  */
2272 int 
2273 usb_register(struct usb_driver *driver)
2274 {
2275         rtw_usb_linux_register(driver);
2276         return 0;
2277 }
2278
2279
2280 int 
2281 usb_deregister(struct usb_driver *driver)
2282 {
2283         rtw_usb_linux_deregister(driver);
2284         return 0;
2285 }
2286
2287 void module_init_exit_wrapper(void *arg)
2288 {
2289         int (*func)(void) = arg;
2290         func();
2291         return;
2292 }
2293
2294 #endif //PLATFORM_FREEBSD
2295
2296 #ifdef CONFIG_PLATFORM_SPRD
2297 #ifdef do_div
2298 #undef do_div
2299 #endif
2300 #include <asm-generic/div64.h>
2301 #endif
2302
2303 u64 rtw_modular64(u64 x, u64 y)
2304 {
2305 #ifdef PLATFORM_LINUX
2306         return do_div(x, y);
2307 #elif defined(PLATFORM_WINDOWS)
2308         return (x % y);
2309 #elif defined(PLATFORM_FREEBSD)
2310         return (x %y);
2311 #endif
2312 }
2313
2314 u64 rtw_division64(u64 x, u64 y)
2315 {
2316 #ifdef PLATFORM_LINUX
2317         do_div(x, y);
2318         return x;
2319 #elif defined(PLATFORM_WINDOWS)
2320         return (x / y);
2321 #elif defined(PLATFORM_FREEBSD)
2322         return (x / y);
2323 #endif
2324 }
2325
2326 inline u32 rtw_random32(void)
2327 {
2328 #ifdef PLATFORM_LINUX
2329         #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
2330         return prandom_u32();
2331         #elif (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,18))
2332         u32 random_int;
2333         get_random_bytes( &random_int , 4 );
2334         return random_int;
2335         #else
2336         return random32();
2337         #endif
2338 #elif defined(PLATFORM_WINDOWS)
2339         #error "to be implemented\n"
2340 #elif defined(PLATFORM_FREEBSD)
2341         #error "to be implemented\n"
2342 #endif
2343 }
2344
2345 void rtw_buf_free(u8 **buf, u32 *buf_len)
2346 {
2347         u32 ori_len;
2348
2349         if (!buf || !buf_len)
2350                 return;
2351
2352         ori_len = *buf_len;
2353
2354         if (*buf) {
2355                 u32 tmp_buf_len = *buf_len;
2356                 *buf_len = 0;
2357                 rtw_mfree(*buf, tmp_buf_len);
2358                 *buf = NULL;
2359         }
2360 }
2361
2362 void rtw_buf_update(u8 **buf, u32 *buf_len, u8 *src, u32 src_len)
2363 {
2364         u32 ori_len = 0, dup_len = 0;
2365         u8 *ori = NULL;
2366         u8 *dup = NULL;
2367
2368         if (!buf || !buf_len)
2369                 return;
2370
2371         if (!src || !src_len)
2372                 goto keep_ori;
2373
2374         /* duplicate src */
2375         dup = rtw_malloc(src_len);
2376         if (dup) {
2377                 dup_len = src_len;
2378                 _rtw_memcpy(dup, src, dup_len);
2379         }
2380
2381 keep_ori:
2382         ori = *buf;
2383         ori_len = *buf_len;
2384
2385         /* replace buf with dup */
2386         *buf_len = 0;
2387         *buf = dup;
2388         *buf_len = dup_len;
2389
2390         /* free ori */
2391         if (ori && ori_len > 0)
2392                 rtw_mfree(ori, ori_len);
2393 }
2394
2395
2396 /**
2397  * rtw_cbuf_full - test if cbuf is full
2398  * @cbuf: pointer of struct rtw_cbuf
2399  *
2400  * Returns: _TRUE if cbuf is full
2401  */
2402 inline bool rtw_cbuf_full(struct rtw_cbuf *cbuf)
2403 {
2404         return (cbuf->write == cbuf->read-1)? _TRUE : _FALSE;
2405 }
2406
2407 /**
2408  * rtw_cbuf_empty - test if cbuf is empty
2409  * @cbuf: pointer of struct rtw_cbuf
2410  *
2411  * Returns: _TRUE if cbuf is empty
2412  */
2413 inline bool rtw_cbuf_empty(struct rtw_cbuf *cbuf)
2414 {
2415         return (cbuf->write == cbuf->read)? _TRUE : _FALSE;
2416 }
2417
2418 /**
2419  * rtw_cbuf_push - push a pointer into cbuf
2420  * @cbuf: pointer of struct rtw_cbuf
2421  * @buf: pointer to push in
2422  *
2423  * Lock free operation, be careful of the use scheme
2424  * Returns: _TRUE push success
2425  */
2426 bool rtw_cbuf_push(struct rtw_cbuf *cbuf, void *buf)
2427 {
2428         if (rtw_cbuf_full(cbuf))
2429                 return _FAIL;
2430
2431         if (0)
2432                 DBG_871X("%s on %u\n", __func__, cbuf->write);
2433         cbuf->bufs[cbuf->write] = buf;
2434         cbuf->write = (cbuf->write+1)%cbuf->size;
2435
2436         return _SUCCESS;
2437 }
2438
2439 /**
2440  * rtw_cbuf_pop - pop a pointer from cbuf
2441  * @cbuf: pointer of struct rtw_cbuf
2442  *
2443  * Lock free operation, be careful of the use scheme
2444  * Returns: pointer popped out
2445  */
2446 void *rtw_cbuf_pop(struct rtw_cbuf *cbuf)
2447 {
2448         void *buf;
2449         if (rtw_cbuf_empty(cbuf))
2450                 return NULL;
2451
2452         if (0)
2453                 DBG_871X("%s on %u\n", __func__, cbuf->read);
2454         buf = cbuf->bufs[cbuf->read];
2455         cbuf->read = (cbuf->read+1)%cbuf->size;
2456
2457         return buf;
2458 }
2459
2460 /**
2461  * rtw_cbuf_alloc - allocte a rtw_cbuf with given size and do initialization
2462  * @size: size of pointer
2463  *
2464  * Returns: pointer of srtuct rtw_cbuf, NULL for allocation failure
2465  */
2466 struct rtw_cbuf *rtw_cbuf_alloc(u32 size)
2467 {
2468         struct rtw_cbuf *cbuf;
2469
2470         cbuf = (struct rtw_cbuf *)rtw_malloc(sizeof(*cbuf) + sizeof(void*)*size);
2471
2472         if (cbuf) {
2473                 cbuf->write = cbuf->read = 0;
2474                 cbuf->size = size;
2475         }
2476
2477         return cbuf;
2478 }
2479
2480 /**
2481  * rtw_cbuf_free - free the given rtw_cbuf
2482  * @cbuf: pointer of struct rtw_cbuf to free
2483  */
2484 void rtw_cbuf_free(struct rtw_cbuf *cbuf)
2485 {
2486         rtw_mfree((u8*)cbuf, sizeof(*cbuf) + sizeof(void*)*cbuf->size);
2487 }
2488
2489 /**
2490 * IsHexDigit -
2491 *
2492 * Return        TRUE if chTmp is represent for hex digit
2493 *               FALSE otherwise.
2494 */
2495 inline BOOLEAN IsHexDigit(char chTmp)
2496 {
2497         if ((chTmp >= '0' && chTmp <= '9') ||
2498                 (chTmp >= 'a' && chTmp <= 'f') ||
2499                 (chTmp >= 'A' && chTmp <= 'F'))
2500                 return _TRUE;
2501         else
2502                 return _FALSE;
2503 }
2504
2505 /**
2506 * is_alpha -
2507 *
2508 * Return        TRUE if chTmp is represent for alphabet
2509 *               FALSE otherwise.
2510 */
2511 inline BOOLEAN is_alpha(char chTmp)
2512 {
2513         if ((chTmp >= 'a' && chTmp <= 'z') ||
2514                 (chTmp >= 'A' && chTmp <= 'Z'))
2515                 return _TRUE;
2516         else
2517                 return _FALSE;
2518 }
2519
2520 inline char alpha_to_upper(char c)
2521 {
2522         if ((c >= 'a' && c <= 'z'))
2523                 c = 'A' + (c - 'a');
2524         return c;
2525 }
2526