Commit | Line | Data |
---|---|---|
7bc88639 LF |
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 | * | |
7bc88639 LF |
14 | ******************************************************************************/ |
15 | #define _RTL8188EU_RECV_C_ | |
bc83c4cf | 16 | #include <linux/kmemleak.h> |
7bc88639 LF |
17 | #include <osdep_service.h> |
18 | #include <drv_types.h> | |
19 | #include <recv_osdep.h> | |
20 | #include <mlme_osdep.h> | |
7bc88639 | 21 | |
17452ee9 | 22 | #include <usb_ops_linux.h> |
7bc88639 LF |
23 | #include <wifi.h> |
24 | ||
25 | #include <rtl8188e_hal.h> | |
26 | ||
286fe9b3 | 27 | int rtw_hal_init_recv_priv(struct adapter *padapter) |
7bc88639 LF |
28 | { |
29 | struct recv_priv *precvpriv = &padapter->recvpriv; | |
30 | int i, res = _SUCCESS; | |
31 | struct recv_buf *precvbuf; | |
32 | ||
33 | tasklet_init(&precvpriv->recv_tasklet, | |
34 | (void(*)(unsigned long))rtl8188eu_recv_tasklet, | |
35 | (unsigned long)padapter); | |
36 | ||
37 | /* init recv_buf */ | |
38 | _rtw_init_queue(&precvpriv->free_recv_buf_queue); | |
39 | ||
66ed681a | 40 | precvpriv->pallocated_recv_buf = |
7f399026 | 41 | kcalloc(NR_RECVBUFF, sizeof(struct recv_buf), GFP_KERNEL); |
5228fb63 | 42 | if (!precvpriv->pallocated_recv_buf) { |
7bc88639 | 43 | res = _FAIL; |
66ed681a AR |
44 | RT_TRACE(_module_rtl871x_recv_c_, _drv_err_, |
45 | ("alloc recv_buf fail!\n")); | |
7bc88639 LF |
46 | goto exit; |
47 | } | |
7bc88639 | 48 | |
4246e490 | 49 | precvpriv->precv_buf = precvpriv->pallocated_recv_buf; |
7bc88639 LF |
50 | |
51 | ||
52 | precvbuf = (struct recv_buf *)precvpriv->precv_buf; | |
53 | ||
54 | for (i = 0; i < NR_RECVBUFF; i++) { | |
7bc88639 LF |
55 | res = rtw_os_recvbuf_resource_alloc(padapter, precvbuf); |
56 | if (res == _FAIL) | |
57 | break; | |
7bc88639 LF |
58 | precvbuf->adapter = padapter; |
59 | precvbuf++; | |
60 | } | |
61 | precvpriv->free_recv_buf_queue_cnt = NR_RECVBUFF; | |
62 | skb_queue_head_init(&precvpriv->rx_skb_queue); | |
63 | { | |
64 | int i; | |
65 | size_t tmpaddr = 0; | |
66ed681a | 66 | size_t alignm = 0; |
7bc88639 LF |
67 | struct sk_buff *pskb = NULL; |
68 | ||
69 | skb_queue_head_init(&precvpriv->free_recv_skb_queue); | |
70 | ||
71 | for (i = 0; i < NR_PREALLOC_RECV_SKB; i++) { | |
66ed681a AR |
72 | pskb = __netdev_alloc_skb(padapter->pnetdev, |
73 | MAX_RECVBUF_SZ + RECVBUFF_ALIGN_SZ, | |
74 | GFP_KERNEL); | |
7bc88639 | 75 | if (pskb) { |
bc83c4cf | 76 | kmemleak_not_leak(pskb); |
7bc88639 LF |
77 | pskb->dev = padapter->pnetdev; |
78 | tmpaddr = (size_t)pskb->data; | |
66ed681a AR |
79 | alignm = tmpaddr & (RECVBUFF_ALIGN_SZ-1); |
80 | skb_reserve(pskb, (RECVBUFF_ALIGN_SZ - alignm)); | |
7bc88639 | 81 | |
66ed681a AR |
82 | skb_queue_tail(&precvpriv->free_recv_skb_queue, |
83 | pskb); | |
7bc88639 LF |
84 | } |
85 | pskb = NULL; | |
86 | } | |
87 | } | |
88 | exit: | |
89 | return res; | |
90 | } | |
91 | ||
67f7ada8 | 92 | void rtw_hal_free_recv_priv(struct adapter *padapter) |
7bc88639 LF |
93 | { |
94 | int i; | |
95 | struct recv_buf *precvbuf; | |
96 | struct recv_priv *precvpriv = &padapter->recvpriv; | |
97 | ||
98 | precvbuf = (struct recv_buf *)precvpriv->precv_buf; | |
99 | ||
100 | for (i = 0; i < NR_RECVBUFF; i++) { | |
cba1ce62 | 101 | usb_free_urb(precvbuf->purb); |
7bc88639 LF |
102 | precvbuf++; |
103 | } | |
104 | ||
105 | kfree(precvpriv->pallocated_recv_buf); | |
106 | ||
107 | if (skb_queue_len(&precvpriv->rx_skb_queue)) | |
108 | DBG_88E(KERN_WARNING "rx_skb_queue not empty\n"); | |
109 | skb_queue_purge(&precvpriv->rx_skb_queue); | |
110 | ||
111 | ||
112 | if (skb_queue_len(&precvpriv->free_recv_skb_queue)) | |
66ed681a AR |
113 | DBG_88E(KERN_WARNING "free_recv_skb_queue not empty, %d\n", |
114 | skb_queue_len(&precvpriv->free_recv_skb_queue)); | |
7bc88639 LF |
115 | |
116 | skb_queue_purge(&precvpriv->free_recv_skb_queue); | |
117 | } |