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