rtl8812au_recv.c 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221
  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. #define _RTL8812AU_RECV_C_
  21. //#include <drv_types.h>
  22. #include <rtl8812a_hal.h>
  23. void rtl8812au_init_recvbuf(_adapter *padapter, struct recv_buf *precvbuf)
  24. {
  25. precvbuf->transfer_len = 0;
  26. precvbuf->len = 0;
  27. precvbuf->ref_cnt = 0;
  28. if(precvbuf->pbuf)
  29. {
  30. precvbuf->pdata = precvbuf->phead = precvbuf->ptail = precvbuf->pbuf;
  31. precvbuf->pend = precvbuf->pdata + MAX_RECVBUF_SZ;
  32. }
  33. }
  34. int rtl8812au_init_recv_priv(_adapter *padapter)
  35. {
  36. struct recv_priv *precvpriv = &padapter->recvpriv;
  37. int i, res = _SUCCESS;
  38. struct recv_buf *precvbuf;
  39. #ifdef CONFIG_RECV_THREAD_MODE
  40. _rtw_init_sema(&precvpriv->recv_sema, 0);//will be removed
  41. _rtw_init_sema(&precvpriv->terminate_recvthread_sema, 0);//will be removed
  42. #endif
  43. #ifdef PLATFORM_LINUX
  44. tasklet_init(&precvpriv->recv_tasklet,
  45. (void(*)(unsigned long))rtl8812au_recv_tasklet,
  46. (unsigned long)padapter);
  47. #endif
  48. #ifdef CONFIG_USB_INTERRUPT_IN_PIPE
  49. #ifdef PLATFORM_LINUX
  50. precvpriv->int_in_urb = usb_alloc_urb(0, GFP_KERNEL);
  51. if(precvpriv->int_in_urb == NULL){
  52. res= _FAIL;
  53. DBG_8192C("alloc_urb for interrupt in endpoint fail !!!!\n");
  54. goto exit;
  55. }
  56. #endif
  57. precvpriv->int_in_buf = rtw_zmalloc(INTERRUPT_MSG_FORMAT_LEN);
  58. if(precvpriv->int_in_buf == NULL){
  59. res= _FAIL;
  60. DBG_8192C("alloc_mem for interrupt in endpoint fail !!!!\n");
  61. goto exit;
  62. }
  63. #endif
  64. //init recv_buf
  65. _rtw_init_queue(&precvpriv->free_recv_buf_queue);
  66. #ifdef CONFIG_USE_USB_BUFFER_ALLOC_RX
  67. _rtw_init_queue(&precvpriv->recv_buf_pending_queue);
  68. #endif // CONFIG_USE_USB_BUFFER_ALLOC_RX
  69. precvpriv->pallocated_recv_buf = rtw_zmalloc(NR_RECVBUFF *sizeof(struct recv_buf) + 4);
  70. if(precvpriv->pallocated_recv_buf==NULL){
  71. res= _FAIL;
  72. RT_TRACE(_module_rtl871x_recv_c_,_drv_err_,("alloc recv_buf fail!\n"));
  73. goto exit;
  74. }
  75. _rtw_memset(precvpriv->pallocated_recv_buf, 0, NR_RECVBUFF *sizeof(struct recv_buf) + 4);
  76. precvpriv->precv_buf = (u8 *)N_BYTE_ALIGMENT((SIZE_PTR)(precvpriv->pallocated_recv_buf), 4);
  77. //precvpriv->precv_buf = precvpriv->pallocated_recv_buf + 4 -
  78. // ((uint) (precvpriv->pallocated_recv_buf) &(4-1));
  79. precvbuf = (struct recv_buf*)precvpriv->precv_buf;
  80. for(i=0; i < NR_RECVBUFF ; i++)
  81. {
  82. _rtw_init_listhead(&precvbuf->list);
  83. _rtw_spinlock_init(&precvbuf->recvbuf_lock);
  84. precvbuf->alloc_sz = MAX_RECVBUF_SZ;
  85. res = rtw_os_recvbuf_resource_alloc(padapter, precvbuf);
  86. if(res==_FAIL)
  87. break;
  88. precvbuf->ref_cnt = 0;
  89. precvbuf->adapter =padapter;
  90. //rtw_list_insert_tail(&precvbuf->list, &(precvpriv->free_recv_buf_queue.queue));
  91. precvbuf++;
  92. }
  93. precvpriv->free_recv_buf_queue_cnt = NR_RECVBUFF;
  94. #ifdef PLATFORM_LINUX
  95. skb_queue_head_init(&precvpriv->rx_skb_queue);
  96. #ifdef CONFIG_PREALLOC_RECV_SKB
  97. {
  98. int i;
  99. SIZE_PTR tmpaddr=0;
  100. SIZE_PTR alignment=0;
  101. struct sk_buff *pskb=NULL;
  102. skb_queue_head_init(&precvpriv->free_recv_skb_queue);
  103. for(i=0; i<NR_PREALLOC_RECV_SKB; i++)
  104. {
  105. #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,18)) // http://www.mail-archive.com/netdev@vger.kernel.org/msg17214.html
  106. pskb = __dev_alloc_skb(MAX_RECVBUF_SZ + RECVBUFF_ALIGN_SZ, GFP_KERNEL);
  107. #else
  108. pskb = __netdev_alloc_skb(padapter->pnetdev, MAX_RECVBUF_SZ + RECVBUFF_ALIGN_SZ, GFP_KERNEL);
  109. #endif
  110. if(pskb)
  111. {
  112. pskb->dev = padapter->pnetdev;
  113. tmpaddr = (SIZE_PTR)pskb->data;
  114. alignment = tmpaddr & (RECVBUFF_ALIGN_SZ-1);
  115. skb_reserve(pskb, (RECVBUFF_ALIGN_SZ - alignment));
  116. skb_queue_tail(&precvpriv->free_recv_skb_queue, pskb);
  117. }
  118. pskb=NULL;
  119. }
  120. }
  121. #endif
  122. #endif
  123. exit:
  124. return res;
  125. }
  126. void rtl8812au_free_recv_priv (_adapter *padapter)
  127. {
  128. int i;
  129. struct recv_buf *precvbuf;
  130. struct recv_priv *precvpriv = &padapter->recvpriv;
  131. precvbuf = (struct recv_buf *)precvpriv->precv_buf;
  132. for(i=0; i < NR_RECVBUFF ; i++)
  133. {
  134. rtw_os_recvbuf_resource_free(padapter, precvbuf);
  135. precvbuf++;
  136. }
  137. if(precvpriv->pallocated_recv_buf)
  138. rtw_mfree(precvpriv->pallocated_recv_buf, NR_RECVBUFF *sizeof(struct recv_buf) + 4);
  139. #ifdef CONFIG_USB_INTERRUPT_IN_PIPE
  140. #ifdef PLATFORM_LINUX
  141. if(precvpriv->int_in_urb)
  142. {
  143. usb_free_urb(precvpriv->int_in_urb);
  144. }
  145. #endif//PLATFORM_LINUX
  146. if(precvpriv->int_in_buf)
  147. rtw_mfree(precvpriv->int_in_buf, INTERRUPT_MSG_FORMAT_LEN);
  148. #endif//CONFIG_USB_INTERRUPT_IN_PIPE
  149. #ifdef PLATFORM_LINUX
  150. if (skb_queue_len(&precvpriv->rx_skb_queue)) {
  151. DBG_8192C(KERN_WARNING "rx_skb_queue not empty\n");
  152. }
  153. skb_queue_purge(&precvpriv->rx_skb_queue);
  154. #ifdef CONFIG_PREALLOC_RECV_SKB
  155. if (skb_queue_len(&precvpriv->free_recv_skb_queue)) {
  156. DBG_8192C(KERN_WARNING "free_recv_skb_queue not empty, %d\n", skb_queue_len(&precvpriv->free_recv_skb_queue));
  157. }
  158. skb_queue_purge(&precvpriv->free_recv_skb_queue);
  159. #endif
  160. #endif
  161. }