ARM64: DTS: Add rk3399-firefly uart4 device, node as /dev/ttyS1
[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(%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 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         #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 36))
1408         if (ms < 20) {
1409                 unsigned long us = ms * 1000UL;
1410                 usleep_range(us, us + 1000UL);
1411         } else
1412         #endif
1413         msleep((unsigned int)ms);
1414
1415 #endif  
1416 #ifdef PLATFORM_FREEBSD
1417        //Delay for delay microseconds 
1418         DELAY(ms*1000);
1419         return ;
1420 #endif  
1421 #ifdef PLATFORM_WINDOWS
1422
1423         NdisMSleep(ms*1000); //(us)*1000=(ms)
1424
1425 #endif
1426
1427
1428 }
1429 void rtw_usleep_os(int us)
1430 {
1431 #ifdef PLATFORM_LINUX
1432
1433         // msleep((unsigned int)us);
1434         #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 36))
1435         usleep_range(us, us + 1);       
1436         #else
1437         if ( 1 < (us/1000) )
1438                 msleep(1);
1439       else
1440                 msleep( (us/1000) + 1);
1441         #endif
1442 #endif
1443
1444 #ifdef PLATFORM_FREEBSD
1445         //Delay for delay microseconds 
1446         DELAY(us);
1447
1448         return ;
1449 #endif  
1450 #ifdef PLATFORM_WINDOWS
1451
1452         NdisMSleep(us); //(us)
1453
1454 #endif
1455
1456
1457 }
1458
1459
1460 #ifdef DBG_DELAY_OS
1461 void _rtw_mdelay_os(int ms, const char *func, const int line)
1462 {
1463         #if 0
1464         if(ms>10)
1465                 DBG_871X("%s:%d %s(%d)\n", func, line, __FUNCTION__, ms);
1466                 rtw_msleep_os(ms);
1467         return;
1468         #endif
1469
1470
1471         DBG_871X("%s:%d %s(%d)\n", func, line, __FUNCTION__, ms);
1472
1473 #if defined(PLATFORM_LINUX)
1474
1475         mdelay((unsigned long)ms); 
1476
1477 #elif defined(PLATFORM_WINDOWS)
1478
1479         NdisStallExecution(ms*1000); //(us)*1000=(ms)
1480
1481 #endif
1482
1483
1484 }
1485 void _rtw_udelay_os(int us, const char *func, const int line)
1486 {
1487
1488         #if 0
1489         if(us > 1000) {
1490         DBG_871X("%s:%d %s(%d)\n", func, line, __FUNCTION__, us);
1491                 rtw_usleep_os(us);
1492                 return;
1493         }
1494         #endif 
1495
1496
1497         DBG_871X("%s:%d %s(%d)\n", func, line, __FUNCTION__, us);
1498         
1499         
1500 #if defined(PLATFORM_LINUX)
1501
1502       udelay((unsigned long)us); 
1503
1504 #elif defined(PLATFORM_WINDOWS)
1505
1506         NdisStallExecution(us); //(us)
1507
1508 #endif
1509
1510 }
1511 #else
1512 void rtw_mdelay_os(int ms)
1513 {
1514
1515 #ifdef PLATFORM_LINUX
1516
1517         mdelay((unsigned long)ms); 
1518
1519 #endif  
1520 #ifdef PLATFORM_FREEBSD
1521         DELAY(ms*1000);
1522         return ;
1523 #endif  
1524 #ifdef PLATFORM_WINDOWS
1525
1526         NdisStallExecution(ms*1000); //(us)*1000=(ms)
1527
1528 #endif
1529
1530
1531 }
1532 void rtw_udelay_os(int us)
1533 {
1534
1535 #ifdef PLATFORM_LINUX
1536
1537       udelay((unsigned long)us); 
1538
1539 #endif  
1540 #ifdef PLATFORM_FREEBSD
1541         //Delay for delay microseconds 
1542         DELAY(us);
1543         return ;
1544 #endif          
1545 #ifdef PLATFORM_WINDOWS
1546
1547         NdisStallExecution(us); //(us)
1548
1549 #endif
1550
1551 }
1552 #endif
1553
1554 void rtw_yield_os(void)
1555 {
1556 #ifdef PLATFORM_LINUX
1557         yield();
1558 #endif
1559 #ifdef PLATFORM_FREEBSD
1560         yield();
1561 #endif
1562 #ifdef PLATFORM_WINDOWS
1563         SwitchToThread();
1564 #endif
1565 }
1566
1567 #define RTW_SUSPEND_LOCK_NAME "rtw_wifi"
1568 #define RTW_SUSPEND_EXT_LOCK_NAME "rtw_wifi_ext"
1569 #define RTW_SUSPEND_RX_LOCK_NAME "rtw_wifi_rx"
1570 #define RTW_SUSPEND_TRAFFIC_LOCK_NAME "rtw_wifi_traffic"
1571 #define RTW_SUSPEND_RESUME_LOCK_NAME "rtw_wifi_resume"
1572 #define RTW_RESUME_SCAN_LOCK_NAME "rtw_wifi_scan"
1573 #ifdef CONFIG_WAKELOCK
1574 static struct wake_lock rtw_suspend_lock;
1575 static struct wake_lock rtw_suspend_ext_lock;
1576 static struct wake_lock rtw_suspend_rx_lock;
1577 static struct wake_lock rtw_suspend_traffic_lock;
1578 static struct wake_lock rtw_suspend_resume_lock;
1579 static struct wake_lock rtw_resume_scan_lock;
1580 #elif defined(CONFIG_ANDROID_POWER)
1581 static android_suspend_lock_t rtw_suspend_lock ={
1582         .name = RTW_SUSPEND_LOCK_NAME
1583 };
1584 static android_suspend_lock_t rtw_suspend_ext_lock ={
1585         .name = RTW_SUSPEND_EXT_LOCK_NAME
1586 };
1587 static android_suspend_lock_t rtw_suspend_rx_lock ={
1588         .name = RTW_SUSPEND_RX_LOCK_NAME
1589 };
1590 static android_suspend_lock_t rtw_suspend_traffic_lock ={
1591         .name = RTW_SUSPEND_TRAFFIC_LOCK_NAME
1592 };
1593 static android_suspend_lock_t rtw_suspend_resume_lock ={
1594         .name = RTW_SUSPEND_RESUME_LOCK_NAME
1595 };
1596 static android_suspend_lock_t rtw_resume_scan_lock ={
1597         .name = RTW_RESUME_SCAN_LOCK_NAME
1598 };
1599 #endif
1600
1601 inline void rtw_suspend_lock_init(void)
1602 {
1603         #ifdef CONFIG_WAKELOCK
1604         wake_lock_init(&rtw_suspend_lock, WAKE_LOCK_SUSPEND, RTW_SUSPEND_LOCK_NAME);
1605         wake_lock_init(&rtw_suspend_ext_lock, WAKE_LOCK_SUSPEND, RTW_SUSPEND_EXT_LOCK_NAME);
1606         wake_lock_init(&rtw_suspend_rx_lock, WAKE_LOCK_SUSPEND, RTW_SUSPEND_RX_LOCK_NAME);
1607         wake_lock_init(&rtw_suspend_traffic_lock, WAKE_LOCK_SUSPEND, RTW_SUSPEND_TRAFFIC_LOCK_NAME);
1608         wake_lock_init(&rtw_suspend_resume_lock, WAKE_LOCK_SUSPEND, RTW_SUSPEND_RESUME_LOCK_NAME);
1609         wake_lock_init(&rtw_resume_scan_lock, WAKE_LOCK_SUSPEND, RTW_RESUME_SCAN_LOCK_NAME);
1610         #elif defined(CONFIG_ANDROID_POWER)
1611         android_init_suspend_lock(&rtw_suspend_lock);
1612         android_init_suspend_lock(&rtw_suspend_ext_lock);
1613         android_init_suspend_lock(&rtw_suspend_rx_lock);
1614         android_init_suspend_lock(&rtw_suspend_traffic_lock);
1615         android_init_suspend_lock(&rtw_suspend_resume_lock);
1616         android_init_suspend_lock(&rtw_resume_scan_lock);
1617         #endif
1618 }
1619
1620 inline void rtw_suspend_lock_uninit(void)
1621 {
1622         #ifdef CONFIG_WAKELOCK
1623         wake_lock_destroy(&rtw_suspend_lock);
1624         wake_lock_destroy(&rtw_suspend_ext_lock);
1625         wake_lock_destroy(&rtw_suspend_rx_lock);
1626         wake_lock_destroy(&rtw_suspend_traffic_lock);
1627         wake_lock_destroy(&rtw_suspend_resume_lock);
1628         wake_lock_destroy(&rtw_resume_scan_lock);
1629         #elif defined(CONFIG_ANDROID_POWER)
1630         android_uninit_suspend_lock(&rtw_suspend_lock);
1631         android_uninit_suspend_lock(&rtw_suspend_ext_lock);
1632         android_uninit_suspend_lock(&rtw_suspend_rx_lock);
1633         android_uninit_suspend_lock(&rtw_suspend_traffic_lock);
1634         android_uninit_suspend_lock(&rtw_suspend_resume_lock);
1635         android_uninit_suspend_lock(&rtw_resume_scan_lock);
1636         #endif
1637 }
1638
1639 inline void rtw_lock_suspend(void)
1640 {
1641         #ifdef CONFIG_WAKELOCK
1642         wake_lock(&rtw_suspend_lock);
1643         #elif defined(CONFIG_ANDROID_POWER)
1644         android_lock_suspend(&rtw_suspend_lock);
1645         #endif
1646
1647         #if  defined(CONFIG_WAKELOCK) || defined(CONFIG_ANDROID_POWER)
1648         //DBG_871X("####%s: suspend_lock_count:%d####\n", __FUNCTION__, rtw_suspend_lock.stat.count);
1649         #endif
1650 }
1651
1652 inline void rtw_unlock_suspend(void)
1653 {
1654         #ifdef CONFIG_WAKELOCK
1655         wake_unlock(&rtw_suspend_lock);
1656         #elif defined(CONFIG_ANDROID_POWER)
1657         android_unlock_suspend(&rtw_suspend_lock);
1658         #endif
1659
1660         #if  defined(CONFIG_WAKELOCK) || defined(CONFIG_ANDROID_POWER)
1661         //DBG_871X("####%s: suspend_lock_count:%d####\n", __FUNCTION__, rtw_suspend_lock.stat.count);
1662         #endif
1663 }
1664
1665 inline void rtw_resume_lock_suspend(void)
1666 {
1667         #ifdef CONFIG_WAKELOCK
1668         wake_lock(&rtw_suspend_resume_lock);
1669         #elif defined(CONFIG_ANDROID_POWER)
1670         android_lock_suspend(&rtw_suspend_resume_lock);
1671         #endif
1672
1673         #if  defined(CONFIG_WAKELOCK) || defined(CONFIG_ANDROID_POWER)
1674         //DBG_871X("####%s: suspend_lock_count:%d####\n", __FUNCTION__, rtw_suspend_lock.stat.count);
1675         #endif
1676 }
1677
1678 inline void rtw_resume_unlock_suspend(void)
1679 {
1680         #ifdef CONFIG_WAKELOCK
1681         wake_unlock(&rtw_suspend_resume_lock);
1682         #elif defined(CONFIG_ANDROID_POWER)
1683         android_unlock_suspend(&rtw_suspend_resume_lock);
1684         #endif
1685
1686         #if  defined(CONFIG_WAKELOCK) || defined(CONFIG_ANDROID_POWER)
1687         //DBG_871X("####%s: suspend_lock_count:%d####\n", __FUNCTION__, rtw_suspend_lock.stat.count);
1688         #endif
1689 }
1690
1691 inline void rtw_lock_suspend_timeout(u32 timeout_ms)
1692 {
1693         #ifdef CONFIG_WAKELOCK
1694         wake_lock_timeout(&rtw_suspend_lock, rtw_ms_to_systime(timeout_ms));
1695         #elif defined(CONFIG_ANDROID_POWER)
1696         android_lock_suspend_auto_expire(&rtw_suspend_lock, rtw_ms_to_systime(timeout_ms));
1697         #endif
1698 }
1699
1700 inline void rtw_lock_ext_suspend_timeout(u32 timeout_ms)
1701 {
1702         #ifdef CONFIG_WAKELOCK
1703         wake_lock_timeout(&rtw_suspend_ext_lock, rtw_ms_to_systime(timeout_ms));
1704         #elif defined(CONFIG_ANDROID_POWER)
1705         android_lock_suspend_auto_expire(&rtw_suspend_ext_lock, rtw_ms_to_systime(timeout_ms));
1706         #endif
1707         //DBG_871X("EXT lock timeout:%d\n", timeout_ms);
1708 }
1709
1710 inline void rtw_lock_rx_suspend_timeout(u32 timeout_ms)
1711 {
1712         #ifdef CONFIG_WAKELOCK
1713         wake_lock_timeout(&rtw_suspend_rx_lock, rtw_ms_to_systime(timeout_ms));
1714         #elif defined(CONFIG_ANDROID_POWER)
1715         android_lock_suspend_auto_expire(&rtw_suspend_rx_lock, rtw_ms_to_systime(timeout_ms));
1716         #endif
1717         //DBG_871X("RX lock timeout:%d\n", timeout_ms);
1718 }
1719
1720
1721 inline void rtw_lock_traffic_suspend_timeout(u32 timeout_ms)
1722 {
1723         #ifdef CONFIG_WAKELOCK
1724         wake_lock_timeout(&rtw_suspend_traffic_lock, rtw_ms_to_systime(timeout_ms));
1725         #elif defined(CONFIG_ANDROID_POWER)
1726         android_lock_suspend_auto_expire(&rtw_suspend_traffic_lock, rtw_ms_to_systime(timeout_ms));
1727         #endif
1728         //DBG_871X("traffic lock timeout:%d\n", timeout_ms);
1729 }
1730
1731 inline void rtw_lock_resume_scan_timeout(u32 timeout_ms)
1732 {
1733         #ifdef CONFIG_WAKELOCK
1734         wake_lock_timeout(&rtw_resume_scan_lock, rtw_ms_to_systime(timeout_ms));
1735         #elif defined(CONFIG_ANDROID_POWER)
1736         android_lock_suspend_auto_expire(&rtw_resume_scan_lock, rtw_ms_to_systime(timeout_ms));
1737         #endif
1738         //DBG_871X("resume scan lock:%d\n", timeout_ms);
1739 }
1740
1741 inline void ATOMIC_SET(ATOMIC_T *v, int i)
1742 {
1743         #ifdef PLATFORM_LINUX
1744         atomic_set(v,i);
1745         #elif defined(PLATFORM_WINDOWS)
1746         *v=i;// other choice????
1747         #elif defined(PLATFORM_FREEBSD)
1748         atomic_set_int(v,i);
1749         #endif
1750 }
1751
1752 inline int ATOMIC_READ(ATOMIC_T *v)
1753 {
1754         #ifdef PLATFORM_LINUX
1755         return atomic_read(v);
1756         #elif defined(PLATFORM_WINDOWS)
1757         return *v; // other choice????
1758         #elif defined(PLATFORM_FREEBSD)
1759         return atomic_load_acq_32(v);
1760         #endif
1761 }
1762
1763 inline void ATOMIC_ADD(ATOMIC_T *v, int i)
1764 {
1765         #ifdef PLATFORM_LINUX
1766         atomic_add(i,v);
1767         #elif defined(PLATFORM_WINDOWS)
1768         InterlockedAdd(v,i);
1769         #elif defined(PLATFORM_FREEBSD)
1770         atomic_add_int(v,i);
1771         #endif
1772 }
1773 inline void ATOMIC_SUB(ATOMIC_T *v, int i)
1774 {
1775         #ifdef PLATFORM_LINUX
1776         atomic_sub(i,v);
1777         #elif defined(PLATFORM_WINDOWS)
1778         InterlockedAdd(v,-i);
1779         #elif defined(PLATFORM_FREEBSD)
1780         atomic_subtract_int(v,i);
1781         #endif
1782 }
1783
1784 inline void ATOMIC_INC(ATOMIC_T *v)
1785 {
1786         #ifdef PLATFORM_LINUX
1787         atomic_inc(v);
1788         #elif defined(PLATFORM_WINDOWS)
1789         InterlockedIncrement(v);
1790         #elif defined(PLATFORM_FREEBSD)
1791         atomic_add_int(v,1);
1792         #endif
1793 }
1794
1795 inline void ATOMIC_DEC(ATOMIC_T *v)
1796 {
1797         #ifdef PLATFORM_LINUX
1798         atomic_dec(v);
1799         #elif defined(PLATFORM_WINDOWS)
1800         InterlockedDecrement(v);
1801         #elif defined(PLATFORM_FREEBSD)
1802         atomic_subtract_int(v,1);
1803         #endif
1804 }
1805
1806 inline int ATOMIC_ADD_RETURN(ATOMIC_T *v, int i)
1807 {
1808         #ifdef PLATFORM_LINUX
1809         return atomic_add_return(i,v);
1810         #elif defined(PLATFORM_WINDOWS)
1811         return InterlockedAdd(v,i);
1812         #elif defined(PLATFORM_FREEBSD)
1813         atomic_add_int(v,i);
1814         return atomic_load_acq_32(v);
1815         #endif
1816 }
1817
1818 inline int ATOMIC_SUB_RETURN(ATOMIC_T *v, int i)
1819 {
1820         #ifdef PLATFORM_LINUX
1821         return atomic_sub_return(i,v);
1822         #elif defined(PLATFORM_WINDOWS)
1823         return InterlockedAdd(v,-i);
1824         #elif defined(PLATFORM_FREEBSD)
1825         atomic_subtract_int(v,i);
1826         return atomic_load_acq_32(v);
1827         #endif
1828 }
1829
1830 inline int ATOMIC_INC_RETURN(ATOMIC_T *v)
1831 {
1832         #ifdef PLATFORM_LINUX
1833         return atomic_inc_return(v);
1834         #elif defined(PLATFORM_WINDOWS)
1835         return InterlockedIncrement(v);
1836         #elif defined(PLATFORM_FREEBSD)
1837         atomic_add_int(v,1);
1838         return atomic_load_acq_32(v);
1839         #endif
1840 }
1841
1842 inline int ATOMIC_DEC_RETURN(ATOMIC_T *v)
1843 {
1844         #ifdef PLATFORM_LINUX
1845         return atomic_dec_return(v);
1846         #elif defined(PLATFORM_WINDOWS)
1847         return InterlockedDecrement(v);
1848         #elif defined(PLATFORM_FREEBSD)
1849         atomic_subtract_int(v,1);
1850         return atomic_load_acq_32(v);
1851         #endif
1852 }
1853
1854
1855 #ifdef PLATFORM_LINUX
1856 /*
1857 * Open a file with the specific @param path, @param flag, @param mode
1858 * @param fpp the pointer of struct file pointer to get struct file pointer while file opening is success
1859 * @param path the path of the file to open
1860 * @param flag file operation flags, please refer to linux document
1861 * @param mode please refer to linux document
1862 * @return Linux specific error code
1863 */
1864 static int openFile(struct file **fpp, char *path, int flag, int mode) 
1865
1866         struct file *fp; 
1867  
1868         fp=filp_open(path, flag, mode); 
1869         if(IS_ERR(fp)) {
1870                 *fpp=NULL;
1871                 return PTR_ERR(fp);
1872         }
1873         else {
1874                 *fpp=fp; 
1875                 return 0;
1876         }       
1877 }
1878
1879 /*
1880 * Close the file with the specific @param fp
1881 * @param fp the pointer of struct file to close
1882 * @return always 0
1883 */
1884 static int closeFile(struct file *fp) 
1885
1886         filp_close(fp,NULL);
1887         return 0; 
1888 }
1889
1890 static int readFile(struct file *fp,char *buf,int len) 
1891
1892         int rlen=0, sum=0;
1893         
1894         if (!fp->f_op || !fp->f_op->read) 
1895                 return -EPERM;
1896
1897         while(sum<len) {
1898                 rlen=fp->f_op->read(fp,buf+sum,len-sum, &fp->f_pos);
1899                 if(rlen>0)
1900                         sum+=rlen;
1901                 else if(0 != rlen)
1902                         return rlen;
1903                 else
1904                         break;
1905         }
1906         
1907         return  sum;
1908
1909 }
1910
1911 static int writeFile(struct file *fp,char *buf,int len) 
1912
1913         int wlen=0, sum=0;
1914         
1915         if (!fp->f_op || !fp->f_op->write) 
1916                 return -EPERM; 
1917
1918         while(sum<len) {
1919                 wlen=fp->f_op->write(fp,buf+sum,len-sum, &fp->f_pos);
1920                 if(wlen>0)
1921                         sum+=wlen;
1922                 else if(0 != wlen)
1923                         return wlen;
1924                 else
1925                         break;
1926         }
1927
1928         return sum;
1929
1930 }
1931
1932 /*
1933 * Test if the specifi @param path is a file and readable
1934 * @param path the path of the file to test
1935 * @return Linux specific error code
1936 */
1937 static int isFileReadable(char *path)
1938
1939         struct file *fp;
1940         int ret = 0;
1941         mm_segment_t oldfs;
1942         char buf;
1943  
1944         fp=filp_open(path, O_RDONLY, 0); 
1945         if(IS_ERR(fp)) {
1946                 ret = PTR_ERR(fp);
1947         }
1948         else {
1949                 oldfs = get_fs(); set_fs(get_ds());
1950                 
1951                 if(1!=readFile(fp, &buf, 1))
1952                         ret = PTR_ERR(fp);
1953                 
1954                 set_fs(oldfs);
1955                 filp_close(fp,NULL);
1956         }       
1957         return ret;
1958 }
1959
1960 /*
1961 * Open the file with @param path and retrive the file content into memory starting from @param buf for @param sz at most
1962 * @param path the path of the file to open and read
1963 * @param buf the starting address of the buffer to store file content
1964 * @param sz how many bytes to read at most
1965 * @return the byte we've read, or Linux specific error code
1966 */
1967 static int retriveFromFile(char *path, u8* buf, u32 sz)
1968 {
1969         int ret =-1;
1970         mm_segment_t oldfs;
1971         struct file *fp;
1972
1973         if(path && buf) {
1974                 if( 0 == (ret=openFile(&fp,path, O_RDONLY, 0)) ){
1975                         DBG_871X("%s openFile path:%s fp=%p\n",__FUNCTION__, path ,fp);
1976
1977                         oldfs = get_fs(); set_fs(get_ds());
1978                         ret=readFile(fp, buf, sz);
1979                         set_fs(oldfs);
1980                         closeFile(fp);
1981                         
1982                         DBG_871X("%s readFile, ret:%d\n",__FUNCTION__, ret);
1983                         
1984                 } else {
1985                         DBG_871X("%s openFile path:%s Fail, ret:%d\n",__FUNCTION__, path, ret);
1986                 }
1987         } else {
1988                 DBG_871X("%s NULL pointer\n",__FUNCTION__);
1989                 ret =  -EINVAL;
1990         }
1991         return ret;
1992 }
1993
1994 /*
1995 * Open the file with @param path and wirte @param sz byte of data starting from @param buf into the file
1996 * @param path the path of the file to open and write
1997 * @param buf the starting address of the data to write into file
1998 * @param sz how many bytes to write at most
1999 * @return the byte we've written, or Linux specific error code
2000 */
2001 static int storeToFile(char *path, u8* buf, u32 sz)
2002 {
2003         int ret =0;
2004         mm_segment_t oldfs;
2005         struct file *fp;
2006         
2007         if(path && buf) {
2008                 if( 0 == (ret=openFile(&fp, path, O_CREAT|O_WRONLY, 0666)) ) {
2009                         DBG_871X("%s openFile path:%s fp=%p\n",__FUNCTION__, path ,fp);
2010
2011                         oldfs = get_fs(); set_fs(get_ds());
2012                         ret=writeFile(fp, buf, sz);
2013                         set_fs(oldfs);
2014                         closeFile(fp);
2015
2016                         DBG_871X("%s writeFile, ret:%d\n",__FUNCTION__, ret);
2017                         
2018                 } else {
2019                         DBG_871X("%s openFile path:%s Fail, ret:%d\n",__FUNCTION__, path, ret);
2020                 }       
2021         } else {
2022                 DBG_871X("%s NULL pointer\n",__FUNCTION__);
2023                 ret =  -EINVAL;
2024         }
2025         return ret;
2026 }
2027 #endif //PLATFORM_LINUX
2028
2029 /*
2030 * Test if the specifi @param path is a file and readable
2031 * @param path the path of the file to test
2032 * @return _TRUE or _FALSE
2033 */
2034 int rtw_is_file_readable(char *path)
2035 {
2036 #ifdef PLATFORM_LINUX
2037         if(isFileReadable(path) == 0)
2038                 return _TRUE;
2039         else
2040                 return _FALSE;
2041 #else
2042         //Todo...
2043         return _FALSE;
2044 #endif
2045 }
2046
2047 /*
2048 * Open the file with @param path and retrive the file content into memory starting from @param buf for @param sz at most
2049 * @param path the path of the file to open and read
2050 * @param buf the starting address of the buffer to store file content
2051 * @param sz how many bytes to read at most
2052 * @return the byte we've read
2053 */
2054 int rtw_retrive_from_file(char *path, u8* buf, u32 sz)
2055 {
2056 #ifdef PLATFORM_LINUX
2057         int ret =retriveFromFile(path, buf, sz);
2058         return ret>=0?ret:0;
2059 #else
2060         //Todo...
2061         return 0;
2062 #endif
2063 }
2064
2065 /*
2066 * Open the file with @param path and wirte @param sz byte of data starting from @param buf into the file
2067 * @param path the path of the file to open and write
2068 * @param buf the starting address of the data to write into file
2069 * @param sz how many bytes to write at most
2070 * @return the byte we've written
2071 */
2072 int rtw_store_to_file(char *path, u8* buf, u32 sz)
2073 {
2074 #ifdef PLATFORM_LINUX
2075         int ret =storeToFile(path, buf, sz);
2076         return ret>=0?ret:0;
2077 #else
2078         //Todo...
2079         return 0;
2080 #endif
2081 }
2082
2083 #ifdef PLATFORM_LINUX
2084 struct net_device *rtw_alloc_etherdev_with_old_priv(int sizeof_priv, void *old_priv)
2085 {
2086         struct net_device *pnetdev;
2087         struct rtw_netdev_priv_indicator *pnpi;
2088
2089 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,35))
2090         pnetdev = alloc_etherdev_mq(sizeof(struct rtw_netdev_priv_indicator), 4);
2091 #else
2092         pnetdev = alloc_etherdev(sizeof(struct rtw_netdev_priv_indicator));
2093 #endif
2094         if (!pnetdev)
2095                 goto RETURN;
2096         
2097         pnpi = netdev_priv(pnetdev);
2098         pnpi->priv=old_priv;
2099         pnpi->sizeof_priv=sizeof_priv;
2100
2101 RETURN:
2102         return pnetdev;
2103 }
2104
2105 struct net_device *rtw_alloc_etherdev(int sizeof_priv)
2106 {
2107         struct net_device *pnetdev;
2108         struct rtw_netdev_priv_indicator *pnpi;
2109
2110 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,35))
2111         pnetdev = alloc_etherdev_mq(sizeof(struct rtw_netdev_priv_indicator), 4);
2112 #else
2113         pnetdev = alloc_etherdev(sizeof(struct rtw_netdev_priv_indicator));
2114 #endif
2115         if (!pnetdev)
2116                 goto RETURN;
2117         
2118         pnpi = netdev_priv(pnetdev);
2119         
2120         pnpi->priv = rtw_zvmalloc(sizeof_priv);
2121         if (!pnpi->priv) {
2122                 free_netdev(pnetdev);
2123                 pnetdev = NULL;
2124                 goto RETURN;
2125         }
2126         
2127         pnpi->sizeof_priv=sizeof_priv;
2128 RETURN:
2129         return pnetdev;
2130 }
2131
2132 void rtw_free_netdev(struct net_device * netdev)
2133 {
2134         struct rtw_netdev_priv_indicator *pnpi;
2135         
2136         if(!netdev)
2137                 goto RETURN;
2138         
2139         pnpi = netdev_priv(netdev);
2140
2141         if(!pnpi->priv)
2142                 goto RETURN;
2143
2144         rtw_vmfree(pnpi->priv, pnpi->sizeof_priv);
2145         free_netdev(netdev);
2146
2147 RETURN:
2148         return;
2149 }
2150
2151 /*
2152 * Jeff: this function should be called under ioctl (rtnl_lock is accquired) while 
2153 * LINUX_VERSION_CODE < KERNEL_VERSION(2,6,26)
2154 */
2155 int rtw_change_ifname(_adapter *padapter, const char *ifname)
2156 {
2157         struct net_device *pnetdev;
2158         struct net_device *cur_pnetdev;
2159         struct rereg_nd_name_data *rereg_priv;
2160         int ret;
2161
2162         if(!padapter)
2163                 goto error;
2164
2165         cur_pnetdev = padapter->pnetdev;
2166         rereg_priv = &padapter->rereg_nd_name_priv;
2167         
2168         //free the old_pnetdev
2169         if(rereg_priv->old_pnetdev) {
2170                 free_netdev(rereg_priv->old_pnetdev);
2171                 rereg_priv->old_pnetdev = NULL;
2172         }
2173
2174 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26))
2175         if(!rtnl_is_locked())
2176                 unregister_netdev(cur_pnetdev);
2177         else
2178 #endif
2179                 unregister_netdevice(cur_pnetdev);
2180
2181         rereg_priv->old_pnetdev=cur_pnetdev;
2182
2183         pnetdev = rtw_init_netdev(padapter);
2184         if (!pnetdev)  {
2185                 ret = -1;
2186                 goto error;
2187         }
2188
2189         SET_NETDEV_DEV(pnetdev, dvobj_to_dev(adapter_to_dvobj(padapter)));
2190
2191         rtw_init_netdev_name(pnetdev, ifname);
2192
2193         _rtw_memcpy(pnetdev->dev_addr, adapter_mac_addr(padapter), ETH_ALEN);
2194
2195 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26))
2196         if(!rtnl_is_locked())
2197                 ret = register_netdev(pnetdev);
2198         else
2199 #endif
2200                 ret = register_netdevice(pnetdev);
2201
2202         if ( ret != 0) {
2203                 RT_TRACE(_module_hci_intfs_c_,_drv_err_,("register_netdev() failed\n"));
2204                 goto error;
2205         }
2206
2207         return 0;
2208
2209 error:
2210         
2211         return -1;
2212         
2213 }
2214 #endif
2215
2216 #ifdef PLATFORM_FREEBSD
2217 /*
2218  * Copy a buffer from userspace and write into kernel address 
2219  * space.
2220  *
2221  * This emulation just calls the FreeBSD copyin function (to 
2222  * copy data from user space buffer into a kernel space buffer)
2223  * and is designed to be used with the above io_write_wrapper.
2224  *
2225  * This function should return the number of bytes not copied.
2226  * I.e. success results in a zero value. 
2227  * Negative error values are not returned.
2228  */
2229 unsigned long
2230 copy_from_user(void *to, const void *from, unsigned long n)
2231 {      
2232         if ( copyin(from, to, n) != 0 ) {
2233                 /* Any errors will be treated as a failure
2234                    to copy any of the requested bytes */
2235                 return n;
2236         }
2237
2238         return 0;
2239 }
2240
2241 unsigned long
2242 copy_to_user(void *to, const void *from, unsigned long n)
2243 {
2244         if ( copyout(from, to, n) != 0 ) {
2245                 /* Any errors will be treated as a failure
2246                    to copy any of the requested bytes */
2247                 return n;
2248         }
2249
2250         return 0;
2251 }
2252
2253
2254 /*
2255  * The usb_register and usb_deregister functions are used to register
2256  * usb drivers with the usb subsystem. In this compatibility layer
2257  * emulation a list of drivers (struct usb_driver) is maintained
2258  * and is used for probing/attaching etc.
2259  *
2260  * usb_register and usb_deregister simply call these functions.
2261  */
2262 int 
2263 usb_register(struct usb_driver *driver)
2264 {
2265         rtw_usb_linux_register(driver);
2266         return 0;
2267 }
2268
2269
2270 int 
2271 usb_deregister(struct usb_driver *driver)
2272 {
2273         rtw_usb_linux_deregister(driver);
2274         return 0;
2275 }
2276
2277 void module_init_exit_wrapper(void *arg)
2278 {
2279         int (*func)(void) = arg;
2280         func();
2281         return;
2282 }
2283
2284 #endif //PLATFORM_FREEBSD
2285
2286 #ifdef CONFIG_PLATFORM_SPRD
2287 #ifdef do_div
2288 #undef do_div
2289 #endif
2290 #include <asm-generic/div64.h>
2291 #endif
2292
2293 u64 rtw_modular64(u64 x, u64 y)
2294 {
2295 #ifdef PLATFORM_LINUX
2296         return do_div(x, y);
2297 #elif defined(PLATFORM_WINDOWS)
2298         return (x % y);
2299 #elif defined(PLATFORM_FREEBSD)
2300         return (x %y);
2301 #endif
2302 }
2303
2304 u64 rtw_division64(u64 x, u64 y)
2305 {
2306 #ifdef PLATFORM_LINUX
2307         do_div(x, y);
2308         return x;
2309 #elif defined(PLATFORM_WINDOWS)
2310         return (x / y);
2311 #elif defined(PLATFORM_FREEBSD)
2312         return (x / y);
2313 #endif
2314 }
2315
2316 inline u32 rtw_random32(void)
2317 {
2318 #ifdef PLATFORM_LINUX
2319         #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
2320         return prandom_u32();
2321         #elif (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,18))
2322         u32 random_int;
2323         get_random_bytes( &random_int , 4 );
2324         return random_int;
2325         #else
2326         return random32();
2327         #endif
2328 #elif defined(PLATFORM_WINDOWS)
2329         #error "to be implemented\n"
2330 #elif defined(PLATFORM_FREEBSD)
2331         #error "to be implemented\n"
2332 #endif
2333 }
2334
2335 void rtw_buf_free(u8 **buf, u32 *buf_len)
2336 {
2337         u32 ori_len;
2338
2339         if (!buf || !buf_len)
2340                 return;
2341
2342         ori_len = *buf_len;
2343
2344         if (*buf) {
2345                 u32 tmp_buf_len = *buf_len;
2346                 *buf_len = 0;
2347                 rtw_mfree(*buf, tmp_buf_len);
2348                 *buf = NULL;
2349         }
2350 }
2351
2352 void rtw_buf_update(u8 **buf, u32 *buf_len, u8 *src, u32 src_len)
2353 {
2354         u32 ori_len = 0, dup_len = 0;
2355         u8 *ori = NULL;
2356         u8 *dup = NULL;
2357
2358         if (!buf || !buf_len)
2359                 return;
2360
2361         if (!src || !src_len)
2362                 goto keep_ori;
2363
2364         /* duplicate src */
2365         dup = rtw_malloc(src_len);
2366         if (dup) {
2367                 dup_len = src_len;
2368                 _rtw_memcpy(dup, src, dup_len);
2369         }
2370
2371 keep_ori:
2372         ori = *buf;
2373         ori_len = *buf_len;
2374
2375         /* replace buf with dup */
2376         *buf_len = 0;
2377         *buf = dup;
2378         *buf_len = dup_len;
2379
2380         /* free ori */
2381         if (ori && ori_len > 0)
2382                 rtw_mfree(ori, ori_len);
2383 }
2384
2385
2386 /**
2387  * rtw_cbuf_full - test if cbuf is full
2388  * @cbuf: pointer of struct rtw_cbuf
2389  *
2390  * Returns: _TRUE if cbuf is full
2391  */
2392 inline bool rtw_cbuf_full(struct rtw_cbuf *cbuf)
2393 {
2394         return (cbuf->write == cbuf->read-1)? _TRUE : _FALSE;
2395 }
2396
2397 /**
2398  * rtw_cbuf_empty - test if cbuf is empty
2399  * @cbuf: pointer of struct rtw_cbuf
2400  *
2401  * Returns: _TRUE if cbuf is empty
2402  */
2403 inline bool rtw_cbuf_empty(struct rtw_cbuf *cbuf)
2404 {
2405         return (cbuf->write == cbuf->read)? _TRUE : _FALSE;
2406 }
2407
2408 /**
2409  * rtw_cbuf_push - push a pointer into cbuf
2410  * @cbuf: pointer of struct rtw_cbuf
2411  * @buf: pointer to push in
2412  *
2413  * Lock free operation, be careful of the use scheme
2414  * Returns: _TRUE push success
2415  */
2416 bool rtw_cbuf_push(struct rtw_cbuf *cbuf, void *buf)
2417 {
2418         if (rtw_cbuf_full(cbuf))
2419                 return _FAIL;
2420
2421         if (0)
2422                 DBG_871X("%s on %u\n", __func__, cbuf->write);
2423         cbuf->bufs[cbuf->write] = buf;
2424         cbuf->write = (cbuf->write+1)%cbuf->size;
2425
2426         return _SUCCESS;
2427 }
2428
2429 /**
2430  * rtw_cbuf_pop - pop a pointer from cbuf
2431  * @cbuf: pointer of struct rtw_cbuf
2432  *
2433  * Lock free operation, be careful of the use scheme
2434  * Returns: pointer popped out
2435  */
2436 void *rtw_cbuf_pop(struct rtw_cbuf *cbuf)
2437 {
2438         void *buf;
2439         if (rtw_cbuf_empty(cbuf))
2440                 return NULL;
2441
2442         if (0)
2443                 DBG_871X("%s on %u\n", __func__, cbuf->read);
2444         buf = cbuf->bufs[cbuf->read];
2445         cbuf->read = (cbuf->read+1)%cbuf->size;
2446
2447         return buf;
2448 }
2449
2450 /**
2451  * rtw_cbuf_alloc - allocte a rtw_cbuf with given size and do initialization
2452  * @size: size of pointer
2453  *
2454  * Returns: pointer of srtuct rtw_cbuf, NULL for allocation failure
2455  */
2456 struct rtw_cbuf *rtw_cbuf_alloc(u32 size)
2457 {
2458         struct rtw_cbuf *cbuf;
2459
2460         cbuf = (struct rtw_cbuf *)rtw_malloc(sizeof(*cbuf) + sizeof(void*)*size);
2461
2462         if (cbuf) {
2463                 cbuf->write = cbuf->read = 0;
2464                 cbuf->size = size;
2465         }
2466
2467         return cbuf;
2468 }
2469
2470 /**
2471  * rtw_cbuf_free - free the given rtw_cbuf
2472  * @cbuf: pointer of struct rtw_cbuf to free
2473  */
2474 void rtw_cbuf_free(struct rtw_cbuf *cbuf)
2475 {
2476         rtw_mfree((u8*)cbuf, sizeof(*cbuf) + sizeof(void*)*cbuf->size);
2477 }
2478