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 ******************************************************************************/
20 #define _RTL8723BU_RECV_C_
22 #include <rtl8723b_hal.h>
24 int rtl8723bu_init_recv_priv(_adapter *padapter)
26 struct recv_priv *precvpriv = &padapter->recvpriv;
27 int i, res = _SUCCESS;
28 struct recv_buf *precvbuf;
30 #ifdef CONFIG_RECV_THREAD_MODE
31 _rtw_init_sema(&precvpriv->recv_sema, 0);//will be removed
32 _rtw_init_sema(&precvpriv->terminate_recvthread_sema, 0);//will be removed
36 tasklet_init(&precvpriv->recv_tasklet,
37 (void(*)(unsigned long))usb_recv_tasklet,
38 (unsigned long)padapter);
41 #ifdef CONFIG_USB_INTERRUPT_IN_PIPE
43 precvpriv->int_in_urb = usb_alloc_urb(0, GFP_KERNEL);
44 if(precvpriv->int_in_urb == NULL){
45 DBG_8192C("alloc_urb for interrupt in endpoint fail !!!!\n");
48 precvpriv->int_in_buf = rtw_zmalloc(USB_INTR_CONTENT_LENGTH);
49 if(precvpriv->int_in_buf == NULL){
50 DBG_8192C("alloc_mem for interrupt in endpoint fail !!!!\n");
55 _rtw_init_queue(&precvpriv->free_recv_buf_queue);
57 _rtw_init_queue(&precvpriv->recv_buf_pending_queue);
59 precvpriv->pallocated_recv_buf = rtw_zmalloc(NR_RECVBUFF *sizeof(struct recv_buf) + 4);
60 if(precvpriv->pallocated_recv_buf==NULL){
62 RT_TRACE(_module_rtl871x_recv_c_,_drv_err_,("alloc recv_buf fail!\n"));
65 _rtw_memset(precvpriv->pallocated_recv_buf, 0, NR_RECVBUFF *sizeof(struct recv_buf) + 4);
67 precvpriv->precv_buf = (u8 *)N_BYTE_ALIGMENT((SIZE_PTR)(precvpriv->pallocated_recv_buf), 4);
68 //precvpriv->precv_buf = precvpriv->pallocated_recv_buf + 4 -
69 // ((uint) (precvpriv->pallocated_recv_buf) &(4-1));
72 precvbuf = (struct recv_buf*)precvpriv->precv_buf;
74 for(i=0; i < NR_RECVBUFF ; i++)
76 _rtw_init_listhead(&precvbuf->list);
78 _rtw_spinlock_init(&precvbuf->recvbuf_lock);
80 precvbuf->alloc_sz = MAX_RECVBUF_SZ;
82 res = rtw_os_recvbuf_resource_alloc(padapter, precvbuf);
86 precvbuf->ref_cnt = 0;
87 precvbuf->adapter =padapter;
90 //rtw_list_insert_tail(&precvbuf->list, &(precvpriv->free_recv_buf_queue.queue));
96 precvpriv->free_recv_buf_queue_cnt = NR_RECVBUFF;
100 skb_queue_head_init(&precvpriv->rx_skb_queue);
102 #ifdef CONFIG_PREALLOC_RECV_SKB
106 SIZE_PTR alignment=0;
107 struct sk_buff *pskb=NULL;
109 skb_queue_head_init(&precvpriv->free_recv_skb_queue);
111 for(i=0; i<NR_PREALLOC_RECV_SKB; i++)
114 #ifdef CONFIG_PREALLOC_RX_SKB_BUFFER
115 pskb = rtw_alloc_skb_premem();
117 pskb = rtw_skb_alloc(MAX_RECVBUF_SZ + RECVBUFF_ALIGN_SZ);
122 pskb->dev = padapter->pnetdev;
124 #ifndef CONFIG_PREALLOC_RX_SKB_BUFFER
125 tmpaddr = (SIZE_PTR)pskb->data;
126 alignment = tmpaddr & (RECVBUFF_ALIGN_SZ-1);
127 skb_reserve(pskb, (RECVBUFF_ALIGN_SZ - alignment));
130 skb_queue_tail(&precvpriv->free_recv_skb_queue, pskb);
147 void rtl8723bu_free_recv_priv (_adapter *padapter)
150 struct recv_buf *precvbuf;
151 struct recv_priv *precvpriv = &padapter->recvpriv;
153 precvbuf = (struct recv_buf *)precvpriv->precv_buf;
155 for(i=0; i < NR_RECVBUFF ; i++)
157 rtw_os_recvbuf_resource_free(padapter, precvbuf);
161 if(precvpriv->pallocated_recv_buf)
162 rtw_mfree(precvpriv->pallocated_recv_buf, NR_RECVBUFF *sizeof(struct recv_buf) + 4);
164 #ifdef CONFIG_USB_INTERRUPT_IN_PIPE
165 #ifdef PLATFORM_LINUX
166 if(precvpriv->int_in_urb)
168 usb_free_urb(precvpriv->int_in_urb);
171 if(precvpriv->int_in_buf)
172 rtw_mfree(precvpriv->int_in_buf, USB_INTR_CONTENT_LENGTH);
175 #ifdef PLATFORM_LINUX
177 if (skb_queue_len(&precvpriv->rx_skb_queue)) {
178 DBG_8192C(KERN_WARNING "rx_skb_queue not empty\n");
181 rtw_skb_queue_purge(&precvpriv->rx_skb_queue);
183 #ifdef CONFIG_PREALLOC_RECV_SKB
185 if (skb_queue_len(&precvpriv->free_recv_skb_queue)) {
186 DBG_8192C(KERN_WARNING "free_recv_skb_queue not empty, %d\n", skb_queue_len(&precvpriv->free_recv_skb_queue));
189 #ifdef CONFIG_PREALLOC_RX_SKB_BUFFER
194 while ((skb = skb_dequeue(&precvpriv->free_recv_skb_queue)) != NULL)
196 if(i<NR_PREALLOC_RECV_SKB)
197 rtw_free_skb_premem(skb);
205 rtw_skb_queue_purge(&precvpriv->free_recv_skb_queue);
206 #endif //CONFIG_PREALLOC_RX_SKB_BUFFER