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 #include <drv_types.h>
25 int usb_init_recv_priv(_adapter *padapter, u16 ini_in_buf_sz)
27 struct recv_priv *precvpriv = &padapter->recvpriv;
28 int i, res = _SUCCESS;
29 struct recv_buf *precvbuf;
31 #ifdef CONFIG_RECV_THREAD_MODE
32 _rtw_init_sema(&precvpriv->recv_sema, 0);//will be removed
33 _rtw_init_sema(&precvpriv->terminate_recvthread_sema, 0);//will be removed
34 #endif /* CONFIG_RECV_THREAD_MODE */
37 tasklet_init(&precvpriv->recv_tasklet,
38 (void(*)(unsigned long))usb_recv_tasklet,
39 (unsigned long)padapter);
40 #endif /* PLATFORM_LINUX */
42 #ifdef PLATFORM_FREEBSD
43 #ifdef CONFIG_RX_INDICATE_QUEUE
44 TASK_INIT(&precvpriv->rx_indicate_tasklet, 0, rtw_rx_indicate_tasklet, padapter);
45 #endif /* CONFIG_RX_INDICATE_QUEUE */
46 #endif /* PLATFORM_FREEBSD */
48 #ifdef CONFIG_USB_INTERRUPT_IN_PIPE
50 precvpriv->int_in_urb = usb_alloc_urb(0, GFP_KERNEL);
51 if(precvpriv->int_in_urb == NULL){
53 DBG_8192C("alloc_urb for interrupt in endpoint fail !!!!\n");
56 #endif /* PLATFORM_LINUX */
57 precvpriv->int_in_buf = rtw_zmalloc(ini_in_buf_sz);
58 if(precvpriv->int_in_buf == NULL){
60 DBG_8192C("alloc_mem for interrupt in endpoint fail !!!!\n");
63 #endif /* CONFIG_USB_INTERRUPT_IN_PIPE */
66 _rtw_init_queue(&precvpriv->free_recv_buf_queue);
67 _rtw_init_queue(&precvpriv->recv_buf_pending_queue);
68 #ifndef CONFIG_USE_USB_BUFFER_ALLOC_RX
69 /* this is used only when RX_IOBUF is sk_buff */
70 skb_queue_head_init(&precvpriv->free_recv_skb_queue);
73 DBG_871X("NR_RECVBUFF: %d\n", NR_RECVBUFF);
74 DBG_871X("MAX_RECVBUF_SZ: %d\n", MAX_RECVBUF_SZ);
75 precvpriv->pallocated_recv_buf = rtw_zmalloc(NR_RECVBUFF *sizeof(struct recv_buf) + 4);
76 if(precvpriv->pallocated_recv_buf==NULL){
78 RT_TRACE(_module_rtl871x_recv_c_,_drv_err_,("alloc recv_buf fail!\n"));
82 precvpriv->precv_buf = (u8 *)N_BYTE_ALIGMENT((SIZE_PTR)(precvpriv->pallocated_recv_buf), 4);
84 precvbuf = (struct recv_buf*)precvpriv->precv_buf;
86 for(i=0; i < NR_RECVBUFF ; i++)
88 _rtw_init_listhead(&precvbuf->list);
90 _rtw_spinlock_init(&precvbuf->recvbuf_lock);
92 precvbuf->alloc_sz = MAX_RECVBUF_SZ;
94 res = rtw_os_recvbuf_resource_alloc(padapter, precvbuf);
98 precvbuf->ref_cnt = 0;
99 precvbuf->adapter =padapter;
101 //rtw_list_insert_tail(&precvbuf->list, &(precvpriv->free_recv_buf_queue.queue));
106 precvpriv->free_recv_buf_queue_cnt = NR_RECVBUFF;
108 #if defined(PLATFORM_LINUX) || defined(PLATFORM_FREEBSD)
110 skb_queue_head_init(&precvpriv->rx_skb_queue);
112 #ifdef CONFIG_RX_INDICATE_QUEUE
113 memset(&precvpriv->rx_indicate_queue, 0, sizeof(struct ifqueue));
114 mtx_init(&precvpriv->rx_indicate_queue.ifq_mtx, "rx_indicate_queue", NULL, MTX_DEF);
115 #endif /* CONFIG_RX_INDICATE_QUEUE */
117 #ifdef CONFIG_PREALLOC_RECV_SKB
121 SIZE_PTR alignment=0;
122 struct sk_buff *pskb=NULL;
124 DBG_871X("NR_PREALLOC_RECV_SKB: %d\n", NR_PREALLOC_RECV_SKB);
125 for(i=0; i<NR_PREALLOC_RECV_SKB; i++)
127 #ifdef CONFIG_PREALLOC_RX_SKB_BUFFER
128 pskb = rtw_alloc_skb_premem();
130 pskb = rtw_skb_alloc(MAX_RECVBUF_SZ + RECVBUFF_ALIGN_SZ);
131 #endif //CONFIG_PREALLOC_RX_SKB_BUFFER
135 #ifdef PLATFORM_FREEBSD
136 pskb->dev = padapter->pifp;
138 pskb->dev = padapter->pnetdev;
139 #endif //PLATFORM_FREEBSD
141 #ifndef CONFIG_PREALLOC_RX_SKB_BUFFER
142 tmpaddr = (SIZE_PTR)pskb->data;
143 alignment = tmpaddr & (RECVBUFF_ALIGN_SZ-1);
144 skb_reserve(pskb, (RECVBUFF_ALIGN_SZ - alignment));
146 skb_queue_tail(&precvpriv->free_recv_skb_queue, pskb);
150 #endif /* CONFIG_PREALLOC_RECV_SKB */
152 #endif /* defined(PLATFORM_LINUX) || defined(PLATFORM_FREEBSD) */
159 void usb_free_recv_priv (_adapter *padapter, u16 ini_in_buf_sz)
162 struct recv_buf *precvbuf;
163 struct recv_priv *precvpriv = &padapter->recvpriv;
165 precvbuf = (struct recv_buf *)precvpriv->precv_buf;
167 for(i=0; i < NR_RECVBUFF ; i++)
169 rtw_os_recvbuf_resource_free(padapter, precvbuf);
173 if(precvpriv->pallocated_recv_buf)
174 rtw_mfree(precvpriv->pallocated_recv_buf, NR_RECVBUFF *sizeof(struct recv_buf) + 4);
176 #ifdef CONFIG_USB_INTERRUPT_IN_PIPE
177 #ifdef PLATFORM_LINUX
178 if(precvpriv->int_in_urb)
180 usb_free_urb(precvpriv->int_in_urb);
183 if(precvpriv->int_in_buf)
184 rtw_mfree(precvpriv->int_in_buf, ini_in_buf_sz);
185 #endif /* CONFIG_USB_INTERRUPT_IN_PIPE */
187 #ifdef PLATFORM_LINUX
189 if (skb_queue_len(&precvpriv->rx_skb_queue)) {
190 DBG_8192C(KERN_WARNING "rx_skb_queue not empty\n");
193 rtw_skb_queue_purge(&precvpriv->rx_skb_queue);
195 if (skb_queue_len(&precvpriv->free_recv_skb_queue)) {
196 DBG_8192C(KERN_WARNING "free_recv_skb_queue not empty, %d\n", skb_queue_len(&precvpriv->free_recv_skb_queue));
199 #if !defined(CONFIG_USE_USB_BUFFER_ALLOC_RX)
200 #if defined(CONFIG_PREALLOC_RECV_SKB) && defined(CONFIG_PREALLOC_RX_SKB_BUFFER)
204 while ((skb = skb_dequeue(&precvpriv->free_recv_skb_queue)) != NULL)
206 if (rtw_free_skb_premem(skb) != 0)
211 rtw_skb_queue_purge(&precvpriv->free_recv_skb_queue);
212 #endif /* defined(CONFIG_PREALLOC_RX_SKB_BUFFER) && defined(CONFIG_PREALLOC_RECV_SKB) */
213 #endif /* !defined(CONFIG_USE_USB_BUFFER_ALLOC_RX) */
215 #endif /* PLATFORM_LINUX */
217 #ifdef PLATFORM_FREEBSD
218 struct sk_buff *pskb;
219 while (NULL != (pskb = skb_dequeue(&precvpriv->rx_skb_queue)))
224 #if !defined(CONFIG_USE_USB_BUFFER_ALLOC_RX)
225 rtw_skb_queue_purge(&precvpriv->free_recv_skb_queue);
228 #ifdef CONFIG_RX_INDICATE_QUEUE
231 IF_DEQUEUE(&precvpriv->rx_indicate_queue, m);
236 mtx_destroy(&precvpriv->rx_indicate_queue.ifq_mtx);
237 #endif /* CONFIG_RX_INDICATE_QUEUE */
239 #endif /* PLATFORM_FREEBSD */
242 #ifdef CONFIG_USB_SUPPORT_ASYNC_VDN_REQ
243 int usb_write_async(struct usb_device *udev, u32 addr, void *pdata, u16 len)
251 requesttype = VENDOR_WRITE;//write_out
252 request = REALTEK_USB_VENQT_CMD_REQ;
253 index = REALTEK_USB_VENQT_CMD_IDX;//n/a
255 wvalue = (u16)(addr&0x0000ffff);
257 ret = _usbctrl_vendorreq_async_write(udev, request, wvalue, index, pdata, len, requesttype);
262 int usb_async_write8(struct intf_hdl *pintfhdl, u32 addr, u8 val)
266 struct dvobj_priv *pdvobjpriv = (struct dvobj_priv *)pintfhdl->pintf_dev;
267 struct usb_device *udev=pdvobjpriv->pusbdev;
271 ret = usb_write_async(udev, addr, &data, 1);
277 int usb_async_write16(struct intf_hdl *pintfhdl, u32 addr, u16 val)
281 struct dvobj_priv *pdvobjpriv = (struct dvobj_priv *)pintfhdl->pintf_dev;
282 struct usb_device *udev=pdvobjpriv->pusbdev;
286 ret = usb_write_async(udev, addr, &data, 2);
292 int usb_async_write32(struct intf_hdl *pintfhdl, u32 addr, u32 val)
296 struct dvobj_priv *pdvobjpriv = (struct dvobj_priv *)pintfhdl->pintf_dev;
297 struct usb_device *udev=pdvobjpriv->pusbdev;
301 ret = usb_write_async(udev, addr, &data, 4);
306 #endif /* CONFIG_USB_SUPPORT_ASYNC_VDN_REQ */
308 u8 usb_read8(struct intf_hdl *pintfhdl, u32 addr)
320 requesttype = 0x01;//read_in
323 wvalue = (u16)(addr&0x0000ffff);
325 usbctrl_vendorreq(pintfhdl, request, wvalue, index,
326 &data, len, requesttype);
333 u16 usb_read16(struct intf_hdl *pintfhdl, u32 addr)
345 requesttype = 0x01;//read_in
348 wvalue = (u16)(addr&0x0000ffff);
350 usbctrl_vendorreq(pintfhdl, request, wvalue, index,
351 &data, len, requesttype);
359 u32 usb_read32(struct intf_hdl *pintfhdl, u32 addr)
371 requesttype = 0x01;//read_in
374 wvalue = (u16)(addr&0x0000ffff);
376 usbctrl_vendorreq(pintfhdl, request, wvalue, index,
377 &data, len, requesttype);
384 int usb_write8(struct intf_hdl *pintfhdl, u32 addr, u8 val)
397 requesttype = 0x00;//write_out
400 wvalue = (u16)(addr&0x0000ffff);
404 ret = usbctrl_vendorreq(pintfhdl, request, wvalue, index,
405 &data, len, requesttype);
412 int usb_write16(struct intf_hdl *pintfhdl, u32 addr, u16 val)
425 requesttype = 0x00;//write_out
428 wvalue = (u16)(addr&0x0000ffff);
432 ret = usbctrl_vendorreq(pintfhdl, request, wvalue, index,
433 &data, len, requesttype);
441 int usb_write32(struct intf_hdl *pintfhdl, u32 addr, u32 val)
454 requesttype = 0x00;//write_out
457 wvalue = (u16)(addr&0x0000ffff);
460 ret = usbctrl_vendorreq(pintfhdl, request, wvalue, index,
461 &data, len, requesttype);
469 int usb_writeN(struct intf_hdl *pintfhdl, u32 addr, u32 length, u8 *pdata)
476 u8 buf[VENDOR_CMD_MAX_DATA_LEN]={0};
482 requesttype = 0x00;//write_out
485 wvalue = (u16)(addr&0x0000ffff);
487 _rtw_memcpy(buf, pdata, len );
488 ret = usbctrl_vendorreq(pintfhdl, request, wvalue, index,
489 buf, len, requesttype);