OSDN Git Service

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