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