1 /******************************************************************************
3 * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
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.
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
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
19 ******************************************************************************/
22 #define _OSDEP_SERVICE_C_
25 #include <osdep_service.h>
26 #include <drv_types.h>
27 #include <recv_osdep.h>
29 #include <linux/vmalloc.h>
31 #ifdef PLATFORM_FREEBSD
32 #include <sys/malloc.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>
43 #ifdef DBG_MEMORY_LEAK
45 #include <asm/atomic.h>
46 atomic_t _malloc_cnt = ATOMIC_INIT(0);
47 atomic_t _malloc_size = ATOMIC_INIT(0);
49 #endif /* DBG_MEMORY_LEAK */
52 #if defined(PLATFORM_LINUX)
54 * Translate the OS dependent @param error_code to OS independent RTW_STATUS_CODE
55 * @return: one of RTW_STATUS_CODE
57 inline int RTW_STATUS_CODE(int error_code){
63 // return RTW_STATUS_TIMEDOUT;
69 inline int RTW_STATUS_CODE(int error_code){
79 for(i=0;i<=strlen(s);i++)
81 if(s[i] >= '0' && s[i] <= '9')
82 num = num * 10 + s[i] -'0';
83 else if(s[0] == '-' && i==0)
96 inline u8* _rtw_vmalloc(u32 sz)
102 #ifdef PLATFORM_FREEBSD
103 pbuf = malloc(sz,M_DEVBUF,M_NOWAIT);
106 #ifdef PLATFORM_WINDOWS
107 NdisAllocateMemoryWithTag(&pbuf,sz, RT_TAG);
110 #ifdef DBG_MEMORY_LEAK
111 #ifdef PLATFORM_LINUX
113 atomic_inc(&_malloc_cnt);
114 atomic_add(sz, &_malloc_size);
117 #endif /* DBG_MEMORY_LEAK */
122 inline u8* _rtw_zvmalloc(u32 sz)
125 #ifdef PLATFORM_LINUX
126 pbuf = _rtw_vmalloc(sz);
130 #ifdef PLATFORM_FREEBSD
131 pbuf = malloc(sz,M_DEVBUF,M_ZERO|M_NOWAIT);
133 #ifdef PLATFORM_WINDOWS
134 NdisAllocateMemoryWithTag(&pbuf,sz, RT_TAG);
136 NdisFillMemory(pbuf, sz, 0);
142 inline void _rtw_vmfree(u8 *pbuf, u32 sz)
144 #ifdef PLATFORM_LINUX
147 #ifdef PLATFORM_FREEBSD
150 #ifdef PLATFORM_WINDOWS
151 NdisFreeMemory(pbuf,sz, 0);
154 #ifdef DBG_MEMORY_LEAK
155 #ifdef PLATFORM_LINUX
156 atomic_dec(&_malloc_cnt);
157 atomic_sub(sz, &_malloc_size);
159 #endif /* DBG_MEMORY_LEAK */
162 u8* _rtw_malloc(u32 sz)
167 #ifdef PLATFORM_LINUX
168 #ifdef RTK_DMP_PLATFORM
170 pbuf = (u8 *)dvr_malloc(sz);
173 pbuf = kmalloc(sz,in_interrupt() ? GFP_ATOMIC : GFP_KERNEL);
176 #ifdef PLATFORM_FREEBSD
177 pbuf = malloc(sz,M_DEVBUF,M_NOWAIT);
179 #ifdef PLATFORM_WINDOWS
181 NdisAllocateMemoryWithTag(&pbuf,sz, RT_TAG);
185 #ifdef DBG_MEMORY_LEAK
186 #ifdef PLATFORM_LINUX
188 atomic_inc(&_malloc_cnt);
189 atomic_add(sz, &_malloc_size);
192 #endif /* DBG_MEMORY_LEAK */
199 u8* _rtw_zmalloc(u32 sz)
201 #ifdef PLATFORM_FREEBSD
202 return malloc(sz,M_DEVBUF,M_ZERO|M_NOWAIT);
203 #else // PLATFORM_FREEBSD
204 u8 *pbuf = _rtw_malloc(sz);
208 #ifdef PLATFORM_LINUX
212 #ifdef PLATFORM_WINDOWS
213 NdisFillMemory(pbuf, sz, 0);
219 #endif // PLATFORM_FREEBSD
222 void _rtw_mfree(u8 *pbuf, u32 sz)
225 #ifdef PLATFORM_LINUX
226 #ifdef RTK_DMP_PLATFORM
234 #ifdef PLATFORM_FREEBSD
237 #ifdef PLATFORM_WINDOWS
239 NdisFreeMemory(pbuf,sz, 0);
243 #ifdef DBG_MEMORY_LEAK
244 #ifdef PLATFORM_LINUX
245 atomic_dec(&_malloc_cnt);
246 atomic_sub(sz, &_malloc_size);
248 #endif /* DBG_MEMORY_LEAK */
252 #ifdef PLATFORM_FREEBSD
254 struct sk_buff * dev_alloc_skb(unsigned int size)
256 struct sk_buff *skb=NULL;
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));
263 data = _rtw_malloc(size);
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;
272 //printf("%s()-%d: skb=%p, skb->head = %p\n", __FUNCTION__, __LINE__, skb, skb->head);
277 _rtw_mfree((u8 *)skb, sizeof(struct sk_buff));
283 void dev_kfree_skb_any(struct sk_buff *skb)
285 //printf("%s()-%d: skb->head = %p\n", __FUNCTION__, __LINE__, skb->head);
287 _rtw_mfree(skb->head, 0);
288 //printf("%s()-%d: skb = %p\n", __FUNCTION__, __LINE__, skb);
290 _rtw_mfree((u8 *)skb, 0);
292 struct sk_buff *skb_clone(const struct sk_buff *skb)
297 #endif /* PLATFORM_FREEBSD */
299 inline struct sk_buff *_rtw_skb_alloc(u32 sz)
301 #ifdef PLATFORM_LINUX
302 return __dev_alloc_skb(sz, in_interrupt() ? GFP_ATOMIC : GFP_KERNEL);
303 #endif /* PLATFORM_LINUX */
305 #ifdef PLATFORM_FREEBSD
306 return dev_alloc_skb(sz);
307 #endif /* PLATFORM_FREEBSD */
310 inline void _rtw_skb_free(struct sk_buff *skb)
312 dev_kfree_skb_any(skb);
315 inline struct sk_buff *_rtw_skb_copy(const struct sk_buff *skb)
317 #ifdef PLATFORM_LINUX
318 return skb_copy(skb, in_interrupt() ? GFP_ATOMIC : GFP_KERNEL);
319 #endif /* PLATFORM_LINUX */
321 #ifdef PLATFORM_FREEBSD
323 #endif /* PLATFORM_FREEBSD */
326 inline struct sk_buff *_rtw_skb_clone(struct sk_buff *skb)
328 #ifdef PLATFORM_LINUX
329 return skb_clone(skb, in_interrupt() ? GFP_ATOMIC : GFP_KERNEL);
330 #endif /* PLATFORM_LINUX */
332 #ifdef PLATFORM_FREEBSD
333 return skb_clone(skb);
334 #endif /* PLATFORM_FREEBSD */
337 inline int _rtw_netif_rx(_nic_hdl ndev, struct sk_buff *skb)
339 #ifdef PLATFORM_LINUX
341 return netif_rx(skb);
342 #endif /* PLATFORM_LINUX */
344 #ifdef PLATFORM_FREEBSD
345 return (*ndev->if_input)(ndev, skb);
346 #endif /* PLATFORM_FREEBSD */
349 void _rtw_skb_queue_purge(struct sk_buff_head *list)
353 while ((skb = skb_dequeue(list)) != NULL)
357 #ifdef CONFIG_USB_HCI
358 inline void *_rtw_usb_buffer_alloc(struct usb_device *dev, size_t size, dma_addr_t *dma)
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);
364 return usb_buffer_alloc(dev, size, (in_interrupt() ? GFP_ATOMIC : GFP_KERNEL), dma);
366 #endif /* PLATFORM_LINUX */
368 #ifdef PLATFORM_FREEBSD
369 return (malloc(size, M_USBDEV, M_NOWAIT | M_ZERO));
370 #endif /* PLATFORM_FREEBSD */
372 inline void _rtw_usb_buffer_free(struct usb_device *dev, size_t size, void *addr, dma_addr_t dma)
374 #ifdef PLATFORM_LINUX
375 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,35))
376 usb_free_coherent(dev, size, addr, dma);
378 usb_buffer_free(dev, size, addr, dma);
380 #endif /* PLATFORM_LINUX */
382 #ifdef PLATFORM_FREEBSD
383 free(addr, M_USBDEV);
384 #endif /* PLATFORM_FREEBSD */
386 #endif /* CONFIG_USB_HCI */
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
397 struct rtw_mem_stat rtw_mem_type_stat[mstat_tf_idx(MSTAT_TYPE_MAX)];
398 #ifdef RTW_MEM_FUNC_STAT
399 struct rtw_mem_stat rtw_mem_func_stat[mstat_ff_idx(MSTAT_FUNC_MAX)];
402 char *MSTAT_TYPE_str[] = {
409 #ifdef RTW_MEM_FUNC_STAT
410 char *MSTAT_FUNC_str[] = {
420 void rtw_mstat_dump(void *sel)
423 int value_t[4][mstat_tf_idx(MSTAT_TYPE_MAX)];
424 #ifdef RTW_MEM_FUNC_STAT
425 int value_f[4][mstat_ff_idx(MSTAT_FUNC_MAX)];
428 int vir_alloc, vir_peak, vir_alloc_err, phy_alloc, phy_peak, phy_alloc_err;
429 int tx_alloc, tx_peak, tx_alloc_err, rx_alloc, rx_peak, rx_alloc_err;
431 for(i=0;i<mstat_tf_idx(MSTAT_TYPE_MAX);i++) {
432 value_t[0][i] = ATOMIC_READ(&(rtw_mem_type_stat[i].alloc));
433 value_t[1][i] = ATOMIC_READ(&(rtw_mem_type_stat[i].peak));
434 value_t[2][i] = ATOMIC_READ(&(rtw_mem_type_stat[i].alloc_cnt));
435 value_t[3][i] = ATOMIC_READ(&(rtw_mem_type_stat[i].alloc_err_cnt));
438 #ifdef RTW_MEM_FUNC_STAT
439 for(i=0;i<mstat_ff_idx(MSTAT_FUNC_MAX);i++) {
440 value_f[0][i] = ATOMIC_READ(&(rtw_mem_func_stat[i].alloc));
441 value_f[1][i] = ATOMIC_READ(&(rtw_mem_func_stat[i].peak));
442 value_f[2][i] = ATOMIC_READ(&(rtw_mem_func_stat[i].alloc_cnt));
443 value_f[3][i] = ATOMIC_READ(&(rtw_mem_func_stat[i].alloc_err_cnt));
447 DBG_871X_SEL_NL(sel, "===================== MSTAT =====================\n");
448 DBG_871X_SEL_NL(sel, "%4s %10s %10s %10s %10s\n", "TAG", "alloc", "peak", "aloc_cnt", "err_cnt");
449 DBG_871X_SEL_NL(sel, "-------------------------------------------------\n");
450 for(i=0;i<mstat_tf_idx(MSTAT_TYPE_MAX);i++) {
451 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]);
453 #ifdef RTW_MEM_FUNC_STAT
454 DBG_871X_SEL_NL(sel, "-------------------------------------------------\n");
455 for(i=0;i<mstat_ff_idx(MSTAT_FUNC_MAX);i++) {
456 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]);
461 void rtw_mstat_update(const enum mstat_f flags, const MSTAT_STATUS status, u32 sz)
463 static u32 update_time = 0;
469 for(i=0;i<mstat_tf_idx(MSTAT_TYPE_MAX);i++) {
470 ATOMIC_SET(&(rtw_mem_type_stat[i].alloc), 0);
471 ATOMIC_SET(&(rtw_mem_type_stat[i].peak), 0);
472 ATOMIC_SET(&(rtw_mem_type_stat[i].alloc_cnt), 0);
473 ATOMIC_SET(&(rtw_mem_type_stat[i].alloc_err_cnt), 0);
475 #ifdef RTW_MEM_FUNC_STAT
476 for(i=0;i<mstat_ff_idx(MSTAT_FUNC_MAX);i++) {
477 ATOMIC_SET(&(rtw_mem_func_stat[i].alloc), 0);
478 ATOMIC_SET(&(rtw_mem_func_stat[i].peak), 0);
479 ATOMIC_SET(&(rtw_mem_func_stat[i].alloc_cnt), 0);
480 ATOMIC_SET(&(rtw_mem_func_stat[i].alloc_err_cnt), 0);
486 case MSTAT_ALLOC_SUCCESS:
487 ATOMIC_INC(&(rtw_mem_type_stat[mstat_tf_idx(flags)].alloc_cnt));
488 alloc = ATOMIC_ADD_RETURN(&(rtw_mem_type_stat[mstat_tf_idx(flags)].alloc), sz);
489 peak=ATOMIC_READ(&(rtw_mem_type_stat[mstat_tf_idx(flags)].peak));
491 ATOMIC_SET(&(rtw_mem_type_stat[mstat_tf_idx(flags)].peak), alloc);
493 #ifdef RTW_MEM_FUNC_STAT
494 ATOMIC_INC(&(rtw_mem_func_stat[mstat_ff_idx(flags)].alloc_cnt));
495 alloc = ATOMIC_ADD_RETURN(&(rtw_mem_func_stat[mstat_ff_idx(flags)].alloc), sz);
496 peak=ATOMIC_READ(&(rtw_mem_func_stat[mstat_ff_idx(flags)].peak));
498 ATOMIC_SET(&(rtw_mem_func_stat[mstat_ff_idx(flags)].peak), alloc);
502 case MSTAT_ALLOC_FAIL:
503 ATOMIC_INC(&(rtw_mem_type_stat[mstat_tf_idx(flags)].alloc_err_cnt));
504 #ifdef RTW_MEM_FUNC_STAT
505 ATOMIC_INC(&(rtw_mem_func_stat[mstat_ff_idx(flags)].alloc_err_cnt));
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 #ifdef RTW_MEM_FUNC_STAT
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);
519 //if (rtw_get_passing_time_ms(update_time) > 5000) {
520 // rtw_mstat_dump(RTW_DBGDUMP);
521 update_time=rtw_get_current_time();
526 #define SIZE_MAX (~(size_t)0)
529 struct mstat_sniff_rule {
535 struct mstat_sniff_rule mstat_sniff_rules[] = {
536 {MSTAT_TYPE_PHY, 4097, SIZE_MAX},
539 int mstat_sniff_rule_num = sizeof(mstat_sniff_rules)/sizeof(struct mstat_sniff_rule);
541 bool match_mstat_sniff_rules(const enum mstat_f flags, const size_t size)
544 for (i = 0; i<mstat_sniff_rule_num; i++) {
545 if (mstat_sniff_rules[i].flags == flags
546 && mstat_sniff_rules[i].lb <= size
547 && mstat_sniff_rules[i].hb >= size)
554 inline u8* dbg_rtw_vmalloc(u32 sz, const enum mstat_f flags, const char *func, const int line)
558 if (match_mstat_sniff_rules(flags, sz))
559 DBG_871X("DBG_MEM_ALLOC %s:%d %s(%d)\n", func, line, __FUNCTION__, (sz));
561 p=_rtw_vmalloc((sz));
565 , p ? MSTAT_ALLOC_SUCCESS : MSTAT_ALLOC_FAIL
572 inline u8* dbg_rtw_zvmalloc(u32 sz, const enum mstat_f flags, const char *func, const int line)
576 if (match_mstat_sniff_rules(flags, sz))
577 DBG_871X("DBG_MEM_ALLOC %s:%d %s(%d)\n", func, line, __FUNCTION__, (sz));
579 p=_rtw_zvmalloc((sz));
583 , p ? MSTAT_ALLOC_SUCCESS : MSTAT_ALLOC_FAIL
590 inline void dbg_rtw_vmfree(u8 *pbuf, u32 sz, const enum mstat_f flags, const char *func, const int line)
593 if (match_mstat_sniff_rules(flags, sz))
594 DBG_871X("DBG_MEM_ALLOC %s:%d %s(%d)\n", func, line, __FUNCTION__, (sz));
596 _rtw_vmfree((pbuf), (sz));
605 inline u8* dbg_rtw_malloc(u32 sz, const enum mstat_f flags, const char *func, const int line)
609 if (match_mstat_sniff_rules(flags, sz))
610 DBG_871X("DBG_MEM_ALLOC %s:%d %s(%d)\n", func, line, __FUNCTION__, (sz));
616 , p ? MSTAT_ALLOC_SUCCESS : MSTAT_ALLOC_FAIL
623 inline u8* dbg_rtw_zmalloc(u32 sz, const enum mstat_f flags, const char *func, const int line)
627 if (match_mstat_sniff_rules(flags, sz))
628 DBG_871X("DBG_MEM_ALLOC %s:%d %s(%d)\n", func, line, __FUNCTION__, (sz));
630 p = _rtw_zmalloc((sz));
634 , p ? MSTAT_ALLOC_SUCCESS : MSTAT_ALLOC_FAIL
641 inline void dbg_rtw_mfree(u8 *pbuf, u32 sz, const enum mstat_f flags, const char *func, const int line)
643 if (match_mstat_sniff_rules(flags, sz))
644 DBG_871X("DBG_MEM_ALLOC %s:%d %s(%d)\n", func, line, __FUNCTION__, (sz));
646 _rtw_mfree((pbuf), (sz));
655 inline struct sk_buff * dbg_rtw_skb_alloc(unsigned int size, const enum mstat_f flags, const char *func, int line)
658 unsigned int truesize = 0;
660 skb = _rtw_skb_alloc(size);
663 truesize = skb->truesize;
665 if(!skb || truesize < size || match_mstat_sniff_rules(flags, truesize))
666 DBG_871X("DBG_MEM_ALLOC %s:%d %s(%d), skb:%p, truesize=%u\n", func, line, __FUNCTION__, size, skb, truesize);
670 , skb ? MSTAT_ALLOC_SUCCESS : MSTAT_ALLOC_FAIL
677 inline void dbg_rtw_skb_free(struct sk_buff *skb, const enum mstat_f flags, const char *func, int line)
679 unsigned int truesize = skb->truesize;
681 if(match_mstat_sniff_rules(flags, truesize))
682 DBG_871X("DBG_MEM_ALLOC %s:%d %s, truesize=%u\n", func, line, __FUNCTION__, truesize);
693 inline struct sk_buff *dbg_rtw_skb_copy(const struct sk_buff *skb, const enum mstat_f flags, const char *func, const int line)
695 struct sk_buff *skb_cp;
696 unsigned int truesize = skb->truesize;
697 unsigned int cp_truesize = 0;
699 skb_cp = _rtw_skb_copy(skb);
701 cp_truesize = skb_cp->truesize;
703 if(!skb_cp || cp_truesize < truesize || match_mstat_sniff_rules(flags, cp_truesize))
704 DBG_871X("DBG_MEM_ALLOC %s:%d %s(%u), skb_cp:%p, cp_truesize=%u\n", func, line, __FUNCTION__, truesize, skb_cp, cp_truesize);
708 , skb_cp ? MSTAT_ALLOC_SUCCESS : MSTAT_ALLOC_FAIL
715 inline struct sk_buff *dbg_rtw_skb_clone(struct sk_buff *skb, const enum mstat_f flags, const char *func, const int line)
717 struct sk_buff *skb_cl;
718 unsigned int truesize = skb->truesize;
719 unsigned int cl_truesize = 0;
721 skb_cl = _rtw_skb_clone(skb);
723 cl_truesize = skb_cl->truesize;
725 if(!skb_cl || cl_truesize < truesize || match_mstat_sniff_rules(flags, cl_truesize))
726 DBG_871X("DBG_MEM_ALLOC %s:%d %s(%u), skb_cl:%p, cl_truesize=%u\n", func, line, __FUNCTION__, truesize, skb_cl, cl_truesize);
730 , skb_cl ? MSTAT_ALLOC_SUCCESS : MSTAT_ALLOC_FAIL
737 inline int dbg_rtw_netif_rx(_nic_hdl ndev, struct sk_buff *skb, const enum mstat_f flags, const char *func, int line)
740 unsigned int truesize = skb->truesize;
742 if(match_mstat_sniff_rules(flags, truesize))
743 DBG_871X("DBG_MEM_ALLOC %s:%d %s, truesize=%u\n", func, line, __FUNCTION__, truesize);
745 ret = _rtw_netif_rx(ndev, skb);
756 inline void dbg_rtw_skb_queue_purge(struct sk_buff_head *list, enum mstat_f flags, const char *func, int line)
760 while ((skb = skb_dequeue(list)) != NULL)
761 dbg_rtw_skb_free(skb, flags, func, line);
764 #ifdef CONFIG_USB_HCI
765 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)
769 if(match_mstat_sniff_rules(flags, size))
770 DBG_871X("DBG_MEM_ALLOC %s:%d %s(%d)\n", func, line, __FUNCTION__, size);
772 p = _rtw_usb_buffer_alloc(dev, size, dma);
776 , p ? MSTAT_ALLOC_SUCCESS : MSTAT_ALLOC_FAIL
783 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)
785 if(match_mstat_sniff_rules(flags, size))
786 DBG_871X("DBG_MEM_ALLOC %s:%d %s(%d)\n", func, line, __FUNCTION__, size);
788 _rtw_usb_buffer_free(dev, size, addr, dma);
796 #endif /* CONFIG_USB_HCI */
797 #endif /* DBG_MEM_ALLOC */
799 void* rtw_malloc2d(int h, int w, int size)
803 void **a = (void **) rtw_zmalloc( h*sizeof(void *) + h*w*size );
806 DBG_871X("%s: alloc memory fail!\n", __FUNCTION__);
811 a[j] = ((char *)(a+h)) + j*w*size;
816 void rtw_mfree2d(void *pbuf, int h, int w, int size)
818 rtw_mfree((u8 *)pbuf, h*sizeof(void*) + w*h*size);
821 void _rtw_memcpy(void* dst, void* src, u32 sz)
824 #if defined (PLATFORM_LINUX)|| defined (PLATFORM_FREEBSD)
826 memcpy(dst, src, sz);
830 #ifdef PLATFORM_WINDOWS
832 NdisMoveMemory(dst, src, sz);
838 int _rtw_memcmp(void *dst, void *src, u32 sz)
841 #if defined (PLATFORM_LINUX)|| defined (PLATFORM_FREEBSD)
842 //under Linux/GNU/GLibc, the return value of memcmp for two same mem. chunk is 0
844 if (!(memcmp(dst, src, sz)))
851 #ifdef PLATFORM_WINDOWS
852 //under Windows, the return value of NdisEqualMemory for two same mem. chunk is 1
854 if (NdisEqualMemory (dst, src, sz))
865 void _rtw_memset(void *pbuf, int c, u32 sz)
868 #if defined (PLATFORM_LINUX)|| defined (PLATFORM_FREEBSD)
874 #ifdef PLATFORM_WINDOWS
876 NdisZeroMemory(pbuf, sz);
877 if (c != 0) memset(pbuf, c, sz);
879 NdisFillMemory(pbuf, sz, c);
885 #ifdef PLATFORM_FREEBSD
886 static inline void __list_add(_list *pnew, _list *pprev, _list *pnext)
893 #endif /* PLATFORM_FREEBSD */
895 void _rtw_init_listhead(_list *list)
898 #ifdef PLATFORM_LINUX
900 INIT_LIST_HEAD(list);
904 #ifdef PLATFORM_FREEBSD
908 #ifdef PLATFORM_WINDOWS
910 NdisInitializeListHead(list);
918 For the following list_xxx operations,
919 caller must guarantee the atomic context.
920 Otherwise, there will be racing condition.
922 u32 rtw_is_list_empty(_list *phead)
925 #ifdef PLATFORM_LINUX
927 if (list_empty(phead))
933 #ifdef PLATFORM_FREEBSD
935 if (phead->next == phead)
943 #ifdef PLATFORM_WINDOWS
945 if (IsListEmpty(phead))
955 void rtw_list_insert_head(_list *plist, _list *phead)
958 #ifdef PLATFORM_LINUX
959 list_add(plist, phead);
962 #ifdef PLATFORM_FREEBSD
963 __list_add(plist, phead, phead->next);
966 #ifdef PLATFORM_WINDOWS
967 InsertHeadList(phead, plist);
971 void rtw_list_insert_tail(_list *plist, _list *phead)
974 #ifdef PLATFORM_LINUX
976 list_add_tail(plist, phead);
979 #ifdef PLATFORM_FREEBSD
981 __list_add(plist, phead->prev, phead);
984 #ifdef PLATFORM_WINDOWS
986 InsertTailList(phead, plist);
995 Caller must check if the list is empty before calling rtw_list_delete
1000 void _rtw_init_sema(_sema *sema, int init_val)
1003 #ifdef PLATFORM_LINUX
1005 sema_init(sema, init_val);
1008 #ifdef PLATFORM_FREEBSD
1009 sema_init(sema, init_val, "rtw_drv");
1011 #ifdef PLATFORM_OS_XP
1013 KeInitializeSemaphore(sema, init_val, SEMA_UPBND); // count=0;
1017 #ifdef PLATFORM_OS_CE
1019 *sema = CreateSemaphore(NULL, init_val, SEMA_UPBND, NULL);
1024 void _rtw_free_sema(_sema *sema)
1026 #ifdef PLATFORM_FREEBSD
1029 #ifdef PLATFORM_OS_CE
1035 void _rtw_up_sema(_sema *sema)
1038 #ifdef PLATFORM_LINUX
1043 #ifdef PLATFORM_FREEBSD
1046 #ifdef PLATFORM_OS_XP
1048 KeReleaseSemaphore(sema, IO_NETWORK_INCREMENT, 1, FALSE );
1052 #ifdef PLATFORM_OS_CE
1053 ReleaseSemaphore(*sema, 1, NULL );
1057 u32 _rtw_down_sema(_sema *sema)
1060 #ifdef PLATFORM_LINUX
1062 if (down_interruptible(sema))
1068 #ifdef PLATFORM_FREEBSD
1072 #ifdef PLATFORM_OS_XP
1074 if(STATUS_SUCCESS == KeWaitForSingleObject(sema, Executive, KernelMode, TRUE, NULL))
1080 #ifdef PLATFORM_OS_CE
1081 if(WAIT_OBJECT_0 == WaitForSingleObject(*sema, INFINITE ))
1090 void _rtw_mutex_init(_mutex *pmutex)
1092 #ifdef PLATFORM_LINUX
1094 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37))
1101 #ifdef PLATFORM_FREEBSD
1102 mtx_init(pmutex, "", NULL, MTX_DEF|MTX_RECURSE);
1104 #ifdef PLATFORM_OS_XP
1106 KeInitializeMutex(pmutex, 0);
1110 #ifdef PLATFORM_OS_CE
1111 *pmutex = CreateMutex( NULL, _FALSE, NULL);
1115 void _rtw_mutex_free(_mutex *pmutex);
1116 void _rtw_mutex_free(_mutex *pmutex)
1118 #ifdef PLATFORM_LINUX
1120 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37))
1121 mutex_destroy(pmutex);
1125 #ifdef PLATFORM_FREEBSD
1126 sema_destroy(pmutex);
1131 #ifdef PLATFORM_OS_XP
1135 #ifdef PLATFORM_OS_CE
1140 void _rtw_spinlock_init(_lock *plock)
1143 #ifdef PLATFORM_LINUX
1145 spin_lock_init(plock);
1148 #ifdef PLATFORM_FREEBSD
1149 mtx_init(plock, "", NULL, MTX_DEF|MTX_RECURSE);
1151 #ifdef PLATFORM_WINDOWS
1153 NdisAllocateSpinLock(plock);
1159 void _rtw_spinlock_free(_lock *plock)
1161 #ifdef PLATFORM_FREEBSD
1165 #ifdef PLATFORM_WINDOWS
1167 NdisFreeSpinLock(plock);
1172 #ifdef PLATFORM_FREEBSD
1173 extern PADAPTER prtw_lock;
1175 void rtw_mtx_lock(_lock *plock){
1177 mtx_lock(&prtw_lock->glock);
1180 printf("%s prtw_lock==NULL",__FUNCTION__);
1183 void rtw_mtx_unlock(_lock *plock){
1185 mtx_unlock(&prtw_lock->glock);
1188 printf("%s prtw_lock==NULL",__FUNCTION__);
1192 #endif //PLATFORM_FREEBSD
1195 void _rtw_spinlock(_lock *plock)
1198 #ifdef PLATFORM_LINUX
1203 #ifdef PLATFORM_FREEBSD
1206 #ifdef PLATFORM_WINDOWS
1208 NdisAcquireSpinLock(plock);
1214 void _rtw_spinunlock(_lock *plock)
1217 #ifdef PLATFORM_LINUX
1222 #ifdef PLATFORM_FREEBSD
1225 #ifdef PLATFORM_WINDOWS
1227 NdisReleaseSpinLock(plock);
1233 void _rtw_spinlock_ex(_lock *plock)
1236 #ifdef PLATFORM_LINUX
1241 #ifdef PLATFORM_FREEBSD
1244 #ifdef PLATFORM_WINDOWS
1246 NdisDprAcquireSpinLock(plock);
1252 void _rtw_spinunlock_ex(_lock *plock)
1255 #ifdef PLATFORM_LINUX
1260 #ifdef PLATFORM_FREEBSD
1263 #ifdef PLATFORM_WINDOWS
1265 NdisDprReleaseSpinLock(plock);
1272 void _rtw_init_queue(_queue *pqueue)
1275 _rtw_init_listhead(&(pqueue->queue));
1277 _rtw_spinlock_init(&(pqueue->lock));
1281 u32 _rtw_queue_empty(_queue *pqueue)
1283 return (rtw_is_list_empty(&(pqueue->queue)));
1287 u32 rtw_end_of_queue_search(_list *head, _list *plist)
1296 u32 rtw_get_current_time(void)
1299 #ifdef PLATFORM_LINUX
1302 #ifdef PLATFORM_FREEBSD
1307 #ifdef PLATFORM_WINDOWS
1308 LARGE_INTEGER SystemTime;
1309 NdisGetCurrentSystemTime(&SystemTime);
1310 return (u32)(SystemTime.LowPart);// count of 100-nanosecond intervals
1314 inline u32 rtw_systime_to_ms(u32 systime)
1316 #ifdef PLATFORM_LINUX
1317 return systime * 1000 / HZ;
1319 #ifdef PLATFORM_FREEBSD
1320 return systime * 1000;
1322 #ifdef PLATFORM_WINDOWS
1323 return systime / 10000 ;
1327 inline u32 rtw_ms_to_systime(u32 ms)
1329 #ifdef PLATFORM_LINUX
1330 return ms * HZ / 1000;
1332 #ifdef PLATFORM_FREEBSD
1335 #ifdef PLATFORM_WINDOWS
1340 // the input parameter start use the same unit as returned by rtw_get_current_time
1341 inline s32 rtw_get_passing_time_ms(u32 start)
1343 #ifdef PLATFORM_LINUX
1344 return rtw_systime_to_ms(jiffies-start);
1346 #ifdef PLATFORM_FREEBSD
1347 return rtw_systime_to_ms(rtw_get_current_time());
1349 #ifdef PLATFORM_WINDOWS
1350 LARGE_INTEGER SystemTime;
1351 NdisGetCurrentSystemTime(&SystemTime);
1352 return rtw_systime_to_ms((u32)(SystemTime.LowPart) - start) ;
1356 inline s32 rtw_get_time_interval_ms(u32 start, u32 end)
1358 #ifdef PLATFORM_LINUX
1359 return rtw_systime_to_ms(end-start);
1361 #ifdef PLATFORM_FREEBSD
1362 return rtw_systime_to_ms(rtw_get_current_time());
1364 #ifdef PLATFORM_WINDOWS
1365 return rtw_systime_to_ms(end-start);
1370 void rtw_sleep_schedulable(int ms)
1373 #ifdef PLATFORM_LINUX
1377 delta = (ms * HZ)/1000;//(ms)
1381 set_current_state(TASK_INTERRUPTIBLE);
1382 if (schedule_timeout(delta) != 0) {
1388 #ifdef PLATFORM_FREEBSD
1393 #ifdef PLATFORM_WINDOWS
1395 NdisMSleep(ms*1000); //(us)*1000=(ms)
1402 void rtw_msleep_os(int ms)
1405 #ifdef PLATFORM_LINUX
1407 msleep((unsigned int)ms);
1410 #ifdef PLATFORM_FREEBSD
1411 //Delay for delay microseconds
1415 #ifdef PLATFORM_WINDOWS
1417 NdisMSleep(ms*1000); //(us)*1000=(ms)
1423 void rtw_usleep_os(int us)
1426 #ifdef PLATFORM_LINUX
1428 // msleep((unsigned int)us);
1429 if ( 1 < (us/1000) )
1432 msleep( (us/1000) + 1);
1435 #ifdef PLATFORM_FREEBSD
1436 //Delay for delay microseconds
1441 #ifdef PLATFORM_WINDOWS
1443 NdisMSleep(us); //(us)
1452 void _rtw_mdelay_os(int ms, const char *func, const int line)
1456 DBG_871X("%s:%d %s(%d)\n", func, line, __FUNCTION__, ms);
1462 DBG_871X("%s:%d %s(%d)\n", func, line, __FUNCTION__, ms);
1464 #if defined(PLATFORM_LINUX)
1466 mdelay((unsigned long)ms);
1468 #elif defined(PLATFORM_WINDOWS)
1470 NdisStallExecution(ms*1000); //(us)*1000=(ms)
1476 void _rtw_udelay_os(int us, const char *func, const int line)
1481 DBG_871X("%s:%d %s(%d)\n", func, line, __FUNCTION__, us);
1488 DBG_871X("%s:%d %s(%d)\n", func, line, __FUNCTION__, us);
1491 #if defined(PLATFORM_LINUX)
1493 udelay((unsigned long)us);
1495 #elif defined(PLATFORM_WINDOWS)
1497 NdisStallExecution(us); //(us)
1503 void rtw_mdelay_os(int ms)
1506 #ifdef PLATFORM_LINUX
1508 mdelay((unsigned long)ms);
1511 #ifdef PLATFORM_FREEBSD
1515 #ifdef PLATFORM_WINDOWS
1517 NdisStallExecution(ms*1000); //(us)*1000=(ms)
1523 void rtw_udelay_os(int us)
1526 #ifdef PLATFORM_LINUX
1528 udelay((unsigned long)us);
1531 #ifdef PLATFORM_FREEBSD
1532 //Delay for delay microseconds
1536 #ifdef PLATFORM_WINDOWS
1538 NdisStallExecution(us); //(us)
1547 #ifdef PLATFORM_LINUX
1550 #ifdef PLATFORM_FREEBSD
1553 #ifdef PLATFORM_WINDOWS
1558 #define RTW_SUSPEND_LOCK_NAME "rtw_wifi"
1560 #ifdef CONFIG_WAKELOCK
1561 static struct wake_lock rtw_suspend_lock;
1562 #elif defined(CONFIG_ANDROID_POWER)
1563 static android_suspend_lock_t rtw_suspend_lock ={
1564 .name = RTW_SUSPEND_LOCK_NAME
1568 inline void rtw_suspend_lock_init()
1570 #ifdef CONFIG_WAKELOCK
1571 wake_lock_init(&rtw_suspend_lock, WAKE_LOCK_SUSPEND, RTW_SUSPEND_LOCK_NAME);
1572 #elif defined(CONFIG_ANDROID_POWER)
1573 android_init_suspend_lock(&rtw_suspend_lock);
1577 inline void rtw_suspend_lock_uninit()
1579 #ifdef CONFIG_WAKELOCK
1580 wake_lock_destroy(&rtw_suspend_lock);
1581 #elif defined(CONFIG_ANDROID_POWER)
1582 android_uninit_suspend_lock(&rtw_suspend_lock);
1586 inline void rtw_lock_suspend()
1588 #ifdef CONFIG_WAKELOCK
1589 wake_lock(&rtw_suspend_lock);
1590 #elif defined(CONFIG_ANDROID_POWER)
1591 android_lock_suspend(&rtw_suspend_lock);
1595 inline void rtw_unlock_suspend()
1597 #ifdef CONFIG_WAKELOCK
1598 wake_unlock(&rtw_suspend_lock);
1599 #elif defined(CONFIG_ANDROID_POWER)
1600 android_unlock_suspend(&rtw_suspend_lock);
1604 inline void rtw_lock_suspend_timeout(u32 timeout_ms)
1606 #ifdef CONFIG_WAKELOCK
1607 wake_lock_timeout(&rtw_suspend_lock, rtw_ms_to_systime(timeout_ms));
1608 #elif defined(CONFIG_ANDROID_POWER)
1609 android_lock_suspend_auto_expire(&rtw_suspend_lock, rtw_ms_to_systime(timeout_ms));
1613 inline void ATOMIC_SET(ATOMIC_T *v, int i)
1615 #ifdef PLATFORM_LINUX
1617 #elif defined(PLATFORM_WINDOWS)
1618 *v=i;// other choice????
1619 #elif defined(PLATFORM_FREEBSD)
1620 atomic_set_int(v,i);
1624 inline int ATOMIC_READ(ATOMIC_T *v)
1626 #ifdef PLATFORM_LINUX
1627 return atomic_read(v);
1628 #elif defined(PLATFORM_WINDOWS)
1629 return *v; // other choice????
1630 #elif defined(PLATFORM_FREEBSD)
1631 return atomic_load_acq_32(v);
1635 inline void ATOMIC_ADD(ATOMIC_T *v, int i)
1637 #ifdef PLATFORM_LINUX
1639 #elif defined(PLATFORM_WINDOWS)
1640 InterlockedAdd(v,i);
1641 #elif defined(PLATFORM_FREEBSD)
1642 atomic_add_int(v,i);
1645 inline void ATOMIC_SUB(ATOMIC_T *v, int i)
1647 #ifdef PLATFORM_LINUX
1649 #elif defined(PLATFORM_WINDOWS)
1650 InterlockedAdd(v,-i);
1651 #elif defined(PLATFORM_FREEBSD)
1652 atomic_subtract_int(v,i);
1656 inline void ATOMIC_INC(ATOMIC_T *v)
1658 #ifdef PLATFORM_LINUX
1660 #elif defined(PLATFORM_WINDOWS)
1661 InterlockedIncrement(v);
1662 #elif defined(PLATFORM_FREEBSD)
1663 atomic_add_int(v,1);
1667 inline void ATOMIC_DEC(ATOMIC_T *v)
1669 #ifdef PLATFORM_LINUX
1671 #elif defined(PLATFORM_WINDOWS)
1672 InterlockedDecrement(v);
1673 #elif defined(PLATFORM_FREEBSD)
1674 atomic_subtract_int(v,1);
1678 inline int ATOMIC_ADD_RETURN(ATOMIC_T *v, int i)
1680 #ifdef PLATFORM_LINUX
1681 return atomic_add_return(i,v);
1682 #elif defined(PLATFORM_WINDOWS)
1683 return InterlockedAdd(v,i);
1684 #elif defined(PLATFORM_FREEBSD)
1685 atomic_add_int(v,i);
1686 return atomic_load_acq_32(v);
1690 inline int ATOMIC_SUB_RETURN(ATOMIC_T *v, int i)
1692 #ifdef PLATFORM_LINUX
1693 return atomic_sub_return(i,v);
1694 #elif defined(PLATFORM_WINDOWS)
1695 return InterlockedAdd(v,-i);
1696 #elif defined(PLATFORM_FREEBSD)
1697 atomic_subtract_int(v,i);
1698 return atomic_load_acq_32(v);
1702 inline int ATOMIC_INC_RETURN(ATOMIC_T *v)
1704 #ifdef PLATFORM_LINUX
1705 return atomic_inc_return(v);
1706 #elif defined(PLATFORM_WINDOWS)
1707 return InterlockedIncrement(v);
1708 #elif defined(PLATFORM_FREEBSD)
1709 atomic_add_int(v,1);
1710 return atomic_load_acq_32(v);
1714 inline int ATOMIC_DEC_RETURN(ATOMIC_T *v)
1716 #ifdef PLATFORM_LINUX
1717 return atomic_dec_return(v);
1718 #elif defined(PLATFORM_WINDOWS)
1719 return InterlockedDecrement(v);
1720 #elif defined(PLATFORM_FREEBSD)
1721 atomic_subtract_int(v,1);
1722 return atomic_load_acq_32(v);
1727 #ifdef PLATFORM_LINUX
1729 * Open a file with the specific @param path, @param flag, @param mode
1730 * @param fpp the pointer of struct file pointer to get struct file pointer while file opening is success
1731 * @param path the path of the file to open
1732 * @param flag file operation flags, please refer to linux document
1733 * @param mode please refer to linux document
1734 * @return Linux specific error code
1736 static int openFile(struct file **fpp, char *path, int flag, int mode)
1740 fp=filp_open(path, flag, mode);
1752 * Close the file with the specific @param fp
1753 * @param fp the pointer of struct file to close
1756 static int closeFile(struct file *fp)
1758 filp_close(fp,NULL);
1762 static int readFile(struct file *fp,char *buf,int len)
1766 if (!fp->f_op || !fp->f_op->read)
1770 rlen=fp->f_op->read(fp,buf+sum,len-sum, &fp->f_pos);
1783 static int writeFile(struct file *fp,char *buf,int len)
1787 if (!fp->f_op || !fp->f_op->write)
1791 wlen=fp->f_op->write(fp,buf+sum,len-sum, &fp->f_pos);
1805 * Test if the specifi @param path is a file and readable
1806 * @param path the path of the file to test
1807 * @return Linux specific error code
1809 static int isFileReadable(char *path)
1816 fp=filp_open(path, O_RDONLY, 0);
1821 oldfs = get_fs(); set_fs(get_ds());
1823 if(1!=readFile(fp, &buf, 1))
1827 filp_close(fp,NULL);
1833 * Open the file with @param path and retrive the file content into memory starting from @param buf for @param sz at most
1834 * @param path the path of the file to open and read
1835 * @param buf the starting address of the buffer to store file content
1836 * @param sz how many bytes to read at most
1837 * @return the byte we've read, or Linux specific error code
1839 static int retriveFromFile(char *path, u8* buf, u32 sz)
1846 if( 0 == (ret=openFile(&fp,path, O_RDONLY, 0)) ){
1847 DBG_871X("%s openFile path:%s fp=%p\n",__FUNCTION__, path ,fp);
1849 oldfs = get_fs(); set_fs(get_ds());
1850 ret=readFile(fp, buf, sz);
1854 DBG_871X("%s readFile, ret:%d\n",__FUNCTION__, ret);
1857 DBG_871X("%s openFile path:%s Fail, ret:%d\n",__FUNCTION__, path, ret);
1860 DBG_871X("%s NULL pointer\n",__FUNCTION__);
1867 * Open the file with @param path and wirte @param sz byte of data starting from @param buf into the file
1868 * @param path the path of the file to open and write
1869 * @param buf the starting address of the data to write into file
1870 * @param sz how many bytes to write at most
1871 * @return the byte we've written, or Linux specific error code
1873 static int storeToFile(char *path, u8* buf, u32 sz)
1880 if( 0 == (ret=openFile(&fp, path, O_CREAT|O_WRONLY, 0666)) ) {
1881 DBG_871X("%s openFile path:%s fp=%p\n",__FUNCTION__, path ,fp);
1883 oldfs = get_fs(); set_fs(get_ds());
1884 ret=writeFile(fp, buf, sz);
1888 DBG_871X("%s writeFile, ret:%d\n",__FUNCTION__, ret);
1891 DBG_871X("%s openFile path:%s Fail, ret:%d\n",__FUNCTION__, path, ret);
1894 DBG_871X("%s NULL pointer\n",__FUNCTION__);
1899 #endif //PLATFORM_LINUX
1902 * Test if the specifi @param path is a file and readable
1903 * @param path the path of the file to test
1904 * @return _TRUE or _FALSE
1906 int rtw_is_file_readable(char *path)
1908 #ifdef PLATFORM_LINUX
1909 if(isFileReadable(path) == 0)
1920 * Open the file with @param path and retrive the file content into memory starting from @param buf for @param sz at most
1921 * @param path the path of the file to open and read
1922 * @param buf the starting address of the buffer to store file content
1923 * @param sz how many bytes to read at most
1924 * @return the byte we've read
1926 int rtw_retrive_from_file(char *path, u8* buf, u32 sz)
1928 #ifdef PLATFORM_LINUX
1929 int ret =retriveFromFile(path, buf, sz);
1930 return ret>=0?ret:0;
1938 * Open the file with @param path and wirte @param sz byte of data starting from @param buf into the file
1939 * @param path the path of the file to open and write
1940 * @param buf the starting address of the data to write into file
1941 * @param sz how many bytes to write at most
1942 * @return the byte we've written
1944 int rtw_store_to_file(char *path, u8* buf, u32 sz)
1946 #ifdef PLATFORM_LINUX
1947 int ret =storeToFile(path, buf, sz);
1948 return ret>=0?ret:0;
1955 #if 1 //#ifdef MEM_ALLOC_REFINE_ADAPTOR
1956 #ifdef PLATFORM_LINUX
1957 struct net_device *rtw_alloc_etherdev_with_old_priv(int sizeof_priv, void *old_priv)
1959 struct net_device *pnetdev;
1960 struct rtw_netdev_priv_indicator *pnpi;
1962 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,35))
1963 pnetdev = alloc_etherdev_mq(sizeof(struct rtw_netdev_priv_indicator), 4);
1965 pnetdev = alloc_etherdev(sizeof(struct rtw_netdev_priv_indicator));
1970 pnpi = netdev_priv(pnetdev);
1971 pnpi->priv=old_priv;
1972 pnpi->sizeof_priv=sizeof_priv;
1978 struct net_device *rtw_alloc_etherdev(int sizeof_priv)
1980 struct net_device *pnetdev;
1981 struct rtw_netdev_priv_indicator *pnpi;
1983 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,35))
1984 pnetdev = alloc_etherdev_mq(sizeof(struct rtw_netdev_priv_indicator), 4);
1986 pnetdev = alloc_etherdev(sizeof(struct rtw_netdev_priv_indicator));
1991 pnpi = netdev_priv(pnetdev);
1993 pnpi->priv = rtw_zvmalloc(sizeof_priv);
1995 free_netdev(pnetdev);
2000 pnpi->sizeof_priv=sizeof_priv;
2005 void rtw_free_netdev(struct net_device * netdev)
2007 struct rtw_netdev_priv_indicator *pnpi;
2012 pnpi = netdev_priv(netdev);
2017 rtw_vmfree(pnpi->priv, pnpi->sizeof_priv);
2018 free_netdev(netdev);
2025 * Jeff: this function should be called under ioctl (rtnl_lock is accquired) while
2026 * LINUX_VERSION_CODE < KERNEL_VERSION(2,6,26)
2028 int rtw_change_ifname(_adapter *padapter, const char *ifname)
2030 struct net_device *pnetdev;
2031 struct net_device *cur_pnetdev = padapter->pnetdev;
2032 struct rereg_nd_name_data *rereg_priv;
2038 rereg_priv = &padapter->rereg_nd_name_priv;
2040 //free the old_pnetdev
2041 if(rereg_priv->old_pnetdev) {
2042 free_netdev(rereg_priv->old_pnetdev);
2043 rereg_priv->old_pnetdev = NULL;
2046 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26))
2047 if(!rtnl_is_locked())
2048 unregister_netdev(cur_pnetdev);
2051 unregister_netdevice(cur_pnetdev);
2053 rereg_priv->old_pnetdev=cur_pnetdev;
2055 pnetdev = rtw_init_netdev(padapter);
2061 SET_NETDEV_DEV(pnetdev, dvobj_to_dev(adapter_to_dvobj(padapter)));
2063 rtw_init_netdev_name(pnetdev, ifname);
2065 _rtw_memcpy(pnetdev->dev_addr, padapter->eeprompriv.mac_addr, ETH_ALEN);
2067 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26))
2068 if(!rtnl_is_locked())
2069 ret = register_netdev(pnetdev);
2072 ret = register_netdevice(pnetdev);
2075 RT_TRACE(_module_hci_intfs_c_,_drv_err_,("register_netdev() failed\n"));
2087 #endif //MEM_ALLOC_REFINE_ADAPTOR
2089 #ifdef PLATFORM_FREEBSD
2091 * Copy a buffer from userspace and write into kernel address
2094 * This emulation just calls the FreeBSD copyin function (to
2095 * copy data from user space buffer into a kernel space buffer)
2096 * and is designed to be used with the above io_write_wrapper.
2098 * This function should return the number of bytes not copied.
2099 * I.e. success results in a zero value.
2100 * Negative error values are not returned.
2103 copy_from_user(void *to, const void *from, unsigned long n)
2105 if ( copyin(from, to, n) != 0 ) {
2106 /* Any errors will be treated as a failure
2107 to copy any of the requested bytes */
2115 copy_to_user(void *to, const void *from, unsigned long n)
2117 if ( copyout(from, to, n) != 0 ) {
2118 /* Any errors will be treated as a failure
2119 to copy any of the requested bytes */
2128 * The usb_register and usb_deregister functions are used to register
2129 * usb drivers with the usb subsystem. In this compatibility layer
2130 * emulation a list of drivers (struct usb_driver) is maintained
2131 * and is used for probing/attaching etc.
2133 * usb_register and usb_deregister simply call these functions.
2136 usb_register(struct usb_driver *driver)
2138 rtw_usb_linux_register(driver);
2144 usb_deregister(struct usb_driver *driver)
2146 rtw_usb_linux_deregister(driver);
2150 void module_init_exit_wrapper(void *arg)
2152 int (*func)(void) = arg;
2157 #endif //PLATFORM_FREEBSD
2158 u64 rtw_modular64(u64 x, u64 y)
2160 #ifdef PLATFORM_LINUX
2161 return do_div(x, y);
2162 #elif defined(PLATFORM_WINDOWS)
2164 #elif defined(PLATFORM_FREEBSD)
2169 u64 rtw_division64(u64 x, u64 y)
2171 #ifdef PLATFORM_LINUX
2174 #elif defined(PLATFORM_WINDOWS)
2176 #elif defined(PLATFORM_FREEBSD)
2181 void rtw_buf_free(u8 **buf, u32 *buf_len)
2185 if (!buf || !buf_len)
2191 u32 tmp_buf_len = *buf_len;
2193 rtw_mfree(*buf, tmp_buf_len);
2198 void rtw_buf_update(u8 **buf, u32 *buf_len, u8 *src, u32 src_len)
2200 u32 ori_len = 0, dup_len = 0;
2204 if (!buf || !buf_len)
2207 if (!src || !src_len)
2211 dup = rtw_malloc(src_len);
2214 _rtw_memcpy(dup, src, dup_len);
2221 /* replace buf with dup */
2227 if (ori && ori_len > 0)
2228 rtw_mfree(ori, ori_len);
2233 * rtw_cbuf_full - test if cbuf is full
2234 * @cbuf: pointer of struct rtw_cbuf
2236 * Returns: _TRUE if cbuf is full
2238 inline bool rtw_cbuf_full(struct rtw_cbuf *cbuf)
2240 return (cbuf->write == cbuf->read-1)? _TRUE : _FALSE;
2244 * rtw_cbuf_empty - test if cbuf is empty
2245 * @cbuf: pointer of struct rtw_cbuf
2247 * Returns: _TRUE if cbuf is empty
2249 inline bool rtw_cbuf_empty(struct rtw_cbuf *cbuf)
2251 return (cbuf->write == cbuf->read)? _TRUE : _FALSE;
2255 * rtw_cbuf_push - push a pointer into cbuf
2256 * @cbuf: pointer of struct rtw_cbuf
2257 * @buf: pointer to push in
2259 * Lock free operation, be careful of the use scheme
2260 * Returns: _TRUE push success
2262 bool rtw_cbuf_push(struct rtw_cbuf *cbuf, void *buf)
2264 if (rtw_cbuf_full(cbuf))
2268 DBG_871X("%s on %u\n", __func__, cbuf->write);
2269 cbuf->bufs[cbuf->write] = buf;
2270 cbuf->write = (cbuf->write+1)%cbuf->size;
2276 * rtw_cbuf_pop - pop a pointer from cbuf
2277 * @cbuf: pointer of struct rtw_cbuf
2279 * Lock free operation, be careful of the use scheme
2280 * Returns: pointer popped out
2282 void *rtw_cbuf_pop(struct rtw_cbuf *cbuf)
2285 if (rtw_cbuf_empty(cbuf))
2289 DBG_871X("%s on %u\n", __func__, cbuf->read);
2290 buf = cbuf->bufs[cbuf->read];
2291 cbuf->read = (cbuf->read+1)%cbuf->size;
2297 * rtw_cbuf_alloc - allocte a rtw_cbuf with given size and do initialization
2298 * @size: size of pointer
2300 * Returns: pointer of srtuct rtw_cbuf, NULL for allocation failure
2302 struct rtw_cbuf *rtw_cbuf_alloc(u32 size)
2304 struct rtw_cbuf *cbuf;
2306 cbuf = (struct rtw_cbuf *)rtw_malloc(sizeof(*cbuf) + sizeof(void*)*size);
2309 cbuf->write = cbuf->read = 0;
2317 * rtw_cbuf_free - free the given rtw_cbuf
2318 * @cbuf: pointer of struct rtw_cbuf to free
2320 void rtw_cbuf_free(struct rtw_cbuf *cbuf)
2322 rtw_mfree((u8*)cbuf, sizeof(*cbuf) + sizeof(void*)*cbuf->size);