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