1 /******************************************************************************
3 * Copyright(c) 2007 - 2012 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 _RTL8723BS_RECV_C_
22 #include <rtl8723b_hal.h>
25 static s32 initrecvbuf(struct recv_buf *precvbuf, PADAPTER padapter)
27 _rtw_init_listhead(&precvbuf->list);
28 _rtw_spinlock_init(&precvbuf->recvbuf_lock);
30 precvbuf->adapter = padapter;
35 static void freerecvbuf(struct recv_buf *precvbuf)
37 _rtw_spinlock_free(&precvbuf->recvbuf_lock);
40 static s32 pre_recv_entry(union recv_frame *precvframe, struct recv_buf *precvbuf, struct phy_stat *pphy_status)
43 #ifdef CONFIG_CONCURRENT_MODE
44 u8 *primary_myid, *secondary_myid, *paddr1;
45 union recv_frame *precvframe_if2 = NULL;
46 _adapter *primary_padapter = precvframe->u.hdr.adapter;
47 _adapter *secondary_padapter = primary_padapter->pbuddy_adapter;
48 struct recv_priv *precvpriv = &primary_padapter->recvpriv;
49 _queue *pfree_recv_queue = &precvpriv->free_recv_queue;
50 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(primary_padapter);
52 if(!secondary_padapter)
55 paddr1 = GetAddr1Ptr(precvframe->u.hdr.rx_data);
57 if(IS_MCAST(paddr1) == _FALSE)//unicast packets
59 //primary_myid = myid(&primary_padapter->eeprompriv);
60 secondary_myid = myid(&secondary_padapter->eeprompriv);
62 if(_rtw_memcmp(paddr1, secondary_myid, ETH_ALEN))
64 //change to secondary interface
65 precvframe->u.hdr.adapter = secondary_padapter;
68 //ret = recv_entry(precvframe);
71 else // Handle BC/MC Packets
74 _pkt *pkt_copy = NULL;
75 struct rx_pkt_attrib *pattrib = NULL;
77 precvframe_if2 = rtw_alloc_recvframe(pfree_recv_queue);
82 precvframe_if2->u.hdr.adapter = secondary_padapter;
83 _rtw_memcpy(&precvframe_if2->u.hdr.attrib, &precvframe->u.hdr.attrib, sizeof(struct rx_pkt_attrib));
84 pattrib = &precvframe_if2->u.hdr.attrib;
86 //driver need to set skb len for skb_copy().
87 //If skb->len is zero, skb_copy() will not copy data from original skb.
88 skb_put(precvframe->u.hdr.pkt, pattrib->pkt_len);
90 pkt_copy = rtw_skb_copy( precvframe->u.hdr.pkt);
93 if((pattrib->mfrag == 1)&&(pattrib->frag_num == 0))
95 DBG_8192C("pre_recv_entry(): rtw_skb_copy fail , drop frag frame \n");
96 rtw_free_recvframe(precvframe, &precvpriv->free_recv_queue);
101 pkt_copy = rtw_skb_clone( precvframe->u.hdr.pkt);
104 DBG_8192C("pre_recv_entry(): rtw_skb_clone fail , drop frame\n");
105 rtw_free_recvframe(precvframe, &precvpriv->free_recv_queue);
111 pkt_copy->dev = secondary_padapter->pnetdev;
113 precvframe_if2->u.hdr.pkt = pkt_copy;
114 precvframe_if2->u.hdr.rx_head = pkt_copy->head;
115 precvframe_if2->u.hdr.rx_data = pkt_copy->data;
116 precvframe_if2->u.hdr.rx_tail = skb_tail_pointer(pkt_copy);
117 precvframe_if2->u.hdr.rx_end = skb_end_pointer(pkt_copy);
118 precvframe_if2->u.hdr.len = pkt_copy->len;
120 //recvframe_put(precvframe_if2, pattrib->pkt_len);
122 if ( pHalData->ReceiveConfig & RCR_APPFCS)
123 recvframe_pull_tail(precvframe_if2, IEEE80211_FCS_LEN);
126 rtl8723b_query_rx_phy_status(precvframe_if2, pphy_status);
128 if(rtw_recv_entry(precvframe_if2) != _SUCCESS)
130 RT_TRACE(_module_rtl871x_recv_c_,_drv_err_,
131 ("recvbuf2recvframe: rtw_recv_entry(precvframe) != _SUCCESS\n"));
140 #ifdef CONFIG_SDIO_RX_COPY
141 static void rtl8723bs_recv_tasklet(void *priv)
144 PHAL_DATA_TYPE pHalData;
145 struct recv_priv *precvpriv;
146 struct recv_buf *precvbuf;
147 union recv_frame *precvframe;
148 struct recv_frame_hdr *phdr;
149 struct rx_pkt_attrib *pattrib;
152 u32 pkt_len, pkt_offset, skb_len, alloc_sz;
153 _pkt *pkt_copy = NULL;
154 u8 shift_sz = 0, rx_report_sz = 0;
157 padapter = (PADAPTER)priv;
158 pHalData = GET_HAL_DATA(padapter);
159 precvpriv = &padapter->recvpriv;
162 precvbuf = rtw_dequeue_recvbuf(&precvpriv->recv_buf_pending_queue);
163 if (NULL == precvbuf) break;
165 ptr = precvbuf->pdata;
167 while (ptr < precvbuf->ptail)
169 precvframe = rtw_alloc_recvframe(&precvpriv->free_recv_queue);
170 if (precvframe == NULL)
172 DBG_8192C("%s: no enough recv frame!\n", __FUNCTION__);
173 rtw_enqueue_recvbuf_to_head(precvbuf, &precvpriv->recv_buf_pending_queue);
175 // The case of can't allocte recvframe should be temporary,
176 // schedule again and hope recvframe is available next time.
177 #ifdef PLATFORM_LINUX
178 tasklet_schedule(&precvpriv->recv_tasklet);
184 rtl8723b_query_rx_desc_status(precvframe, ptr);
186 pattrib = &precvframe->u.hdr.attrib;
188 // fix Hardware RX data error, drop whole recv_buffer
189 if ((!(pHalData->ReceiveConfig & RCR_ACRC32)) && pattrib->crc_err)
192 DBG_8192C("%s()-%d: RX Warning! rx CRC ERROR !!\n", __FUNCTION__, __LINE__);
194 rtw_free_recvframe(precvframe, &precvpriv->free_recv_queue);
198 rx_report_sz = RXDESC_SIZE + pattrib->drvinfo_sz;
199 pkt_offset = rx_report_sz + pattrib->shift_sz + pattrib->pkt_len;
201 if ((ptr + pkt_offset) > precvbuf->ptail) {
202 DBG_8192C("%s()-%d: : next pkt len(%p,%d) exceed ptail(%p)!\n", __FUNCTION__, __LINE__, ptr, pkt_offset, precvbuf->ptail);
203 rtw_free_recvframe(precvframe, &precvpriv->free_recv_queue);
207 if ((pattrib->crc_err) || (pattrib->icv_err))
209 #ifdef CONFIG_MP_INCLUDED
210 if (padapter->registrypriv.mp_mode == 1)
212 if ((check_fwstate(&padapter->mlmepriv, WIFI_MP_STATE) == _TRUE))//&&(padapter->mppriv.check_mp_pkt == 0))
214 if (pattrib->crc_err == 1)
215 padapter->mppriv.rx_crcerrpktcount++;
221 DBG_8192C("%s: crc_err=%d icv_err=%d, skip!\n", __FUNCTION__, pattrib->crc_err, pattrib->icv_err);
223 rtw_free_recvframe(precvframe, &precvpriv->free_recv_queue);
227 // Modified by Albert 20101213
228 // For 8 bytes IP header alignment.
229 if (pattrib->qos) // Qos data, wireless lan header length is 26
238 skb_len = pattrib->pkt_len;
240 // for first fragment packet, driver need allocate 1536+drvinfo_sz+RXDESC_SIZE to defrag packet.
241 // modify alloc_sz for recvive crc error packet by thomas 2011-06-02
242 if((pattrib->mfrag == 1)&&(pattrib->frag_num == 0)){
243 //alloc_sz = 1664; //1664 is 128 alignment.
247 alloc_sz = skb_len + 14;
251 // 6 is for IP header 8 bytes alignment in QoS packet case.
252 // 8 is for skb->data 4 bytes alignment.
256 pkt_copy = rtw_skb_alloc(alloc_sz);
260 pkt_copy->dev = padapter->pnetdev;
261 precvframe->u.hdr.pkt = pkt_copy;
262 skb_reserve( pkt_copy, 8 - ((SIZE_PTR)( pkt_copy->data ) & 7 ));//force pkt_copy->data at 8-byte alignment address
263 skb_reserve( pkt_copy, shift_sz );//force ip_hdr at 8-byte alignment address according to shift_sz.
264 _rtw_memcpy(pkt_copy->data, (ptr + rx_report_sz + pattrib->shift_sz), skb_len);
265 precvframe->u.hdr.rx_head = pkt_copy->head;
266 precvframe->u.hdr.rx_data = precvframe->u.hdr.rx_tail = pkt_copy->data;
267 precvframe->u.hdr.rx_end = skb_end_pointer(pkt_copy);
271 if((pattrib->mfrag == 1)&&(pattrib->frag_num == 0))
273 DBG_8192C("%s: alloc_skb fail, drop frag frame\n", __FUNCTION__);
274 rtw_free_recvframe(precvframe, &precvpriv->free_recv_queue);
278 precvframe->u.hdr.pkt = rtw_skb_clone(precvbuf->pskb);
279 if(precvframe->u.hdr.pkt)
281 _pkt *pkt_clone = precvframe->u.hdr.pkt;
283 pkt_clone->data = ptr + rx_report_sz + pattrib->shift_sz;
284 skb_reset_tail_pointer(pkt_clone);
285 precvframe->u.hdr.rx_head = precvframe->u.hdr.rx_data = precvframe->u.hdr.rx_tail
287 precvframe->u.hdr.rx_end = pkt_clone->data + skb_len;
291 DBG_8192C("%s: rtw_skb_clone fail\n", __FUNCTION__);
292 rtw_free_recvframe(precvframe, &precvpriv->free_recv_queue);
297 recvframe_put(precvframe, skb_len);
298 //recvframe_pull(precvframe, drvinfo_sz + RXDESC_SIZE);
300 if (pHalData->ReceiveConfig & RCR_APPFCS)
301 recvframe_pull_tail(precvframe, IEEE80211_FCS_LEN);
303 // move to drv info position
307 if (pHalData->ReceiveConfig & RCR_APP_BA_SSN) {
308 //rtl8723s_update_bassn(padapter, pdrvinfo);
312 if (pattrib->pkt_rpt_type == NORMAL_RX) {
313 // skip the rx packet with abnormal length
314 if (pattrib->pkt_len < 14 || pattrib->pkt_len > 8192) {
315 DBG_8192C("skip abnormal rx packet(%d)\n", pattrib->pkt_len);
316 rtw_free_recvframe(precvframe, &precvpriv->free_recv_queue);
320 #ifdef CONFIG_CONCURRENT_MODE
321 if (rtw_buddy_adapter_up(padapter))
323 if (pre_recv_entry(precvframe, precvbuf, (struct phy_stat*)ptr) != _SUCCESS) {
324 DBG_8192C(FUNC_ADPT_FMT ": pre_recv_entry(precvframe) != _SUCCESS\n",
325 FUNC_ADPT_ARG(padapter->pbuddy_adapter));
330 rtl8723b_query_rx_phy_status(precvframe, (struct phy_stat*)ptr);
332 if (rtw_recv_entry(precvframe) != _SUCCESS) {
333 RT_TRACE(_module_rtl871x_recv_c_, _drv_dump_, ("%s: rtw_recv_entry(precvframe) != _SUCCESS\n",__FUNCTION__));
337 #ifdef CONFIG_C2H_PACKET_EN
338 if (pattrib->pkt_rpt_type == C2H_PACKET) {
339 rtl8723b_c2h_packet_handler(padapter, precvframe->u.hdr.rx_data, pattrib->pkt_len);
342 DBG_8192C("%s: [WARNNING] RX type(%d) not be handled!\n",
343 __FUNCTION__, pattrib->pkt_rpt_type);
346 rtw_free_recvframe(precvframe, &precvpriv->free_recv_queue);
350 pkt_offset = _RND8(pkt_offset);
351 precvbuf->pdata += pkt_offset;
352 ptr = precvbuf->pdata;
357 rtw_enqueue_recvbuf(precvbuf, &precvpriv->free_recv_buf_queue);
362 static void rtl8723bs_recv_tasklet(void *priv)
365 PHAL_DATA_TYPE pHalData;
366 struct recv_priv *precvpriv;
367 struct recv_buf *precvbuf;
368 union recv_frame *precvframe;
369 struct recv_frame_hdr *phdr;
370 struct rx_pkt_attrib *pattrib;
377 padapter = (PADAPTER)priv;
378 pHalData = GET_HAL_DATA(padapter);
379 precvpriv = &padapter->recvpriv;
382 precvbuf = rtw_dequeue_recvbuf(&precvpriv->recv_buf_pending_queue);
383 if (NULL == precvbuf) break;
385 ptr = precvbuf->pdata;
387 while (ptr < precvbuf->ptail)
389 precvframe = rtw_alloc_recvframe(&precvpriv->free_recv_queue);
390 if (precvframe == NULL) {
391 RT_TRACE(_module_rtl871x_recv_c_, _drv_err_, ("rtl8723bs_recv_tasklet: no enough recv frame!\n"));
392 rtw_enqueue_recvbuf_to_head(precvbuf, &precvpriv->recv_buf_pending_queue);
394 // The case of can't allocte recvframe should be temporary,
395 // schedule again and hope recvframe is available next time.
396 #ifdef PLATFORM_LINUX
397 tasklet_schedule(&precvpriv->recv_tasklet);
402 phdr = &precvframe->u.hdr;
403 pattrib = &phdr->attrib;
405 rtl8723b_query_rx_desc_status(precvframe, ptr);
412 if((*(pptr + RXDESC_SIZE + pattrib->drvinfo_sz) != 0x80) && (*(pptr + RXDESC_SIZE + pattrib->drvinfo_sz) != 0x40))
414 DBG_871X("##############RxDESC############### \n");
415 for(i=0; i<32;i=i+16)
416 DBG_871X("%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:\n", *(pptr+i),
417 *(pptr+i+1), *(pptr+i+2) ,*(pptr+i+3) ,*(pptr+i+4),*(pptr+i+5), *(pptr+i+6), *(pptr+i+7), *(pptr+i+8), *(pptr+i+9), *(pptr+i+10),
418 *(pptr+i+11), *(pptr+i+12), *(pptr+i+13), *(pptr+i+14), *(pptr+i+15));
420 if(pattrib->pkt_len < 100)
421 len = pattrib->pkt_len;
422 pptr = ptr + RXDESC_SIZE + pattrib->drvinfo_sz;
423 DBG_871X("##############Len=%d############### \n", pattrib->pkt_len);
424 for(i=0; i<len;i=i+16)
425 DBG_871X("%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:\n", *(pptr+i),
426 *(pptr+i+1), *(pptr+i+2) ,*(pptr+i+3) ,*(pptr+i+4),*(pptr+i+5), *(pptr+i+6), *(pptr+i+7), *(pptr+i+8), *(pptr+i+9), *(pptr+i+10),
427 *(pptr+i+11), *(pptr+i+12), *(pptr+i+13), *(pptr+i+14), *(pptr+i+15));
428 DBG_871X("############################# \n");
433 // fix Hardware RX data error, drop whole recv_buffer
434 if ((!(pHalData->ReceiveConfig & RCR_ACRC32)) && pattrib->crc_err)
436 DBG_8192C("%s()-%d: RX Warning! rx CRC ERROR !!\n", __FUNCTION__, __LINE__);
437 rtw_free_recvframe(precvframe, &precvpriv->free_recv_queue);
441 pkt_offset = RXDESC_SIZE + pattrib->drvinfo_sz + pattrib->pkt_len;
442 #if 0 // reduce check to speed up
443 if ((ptr + pkt_offset) > precvbuf->ptail) {
444 RT_TRACE(_module_rtl871x_recv_c_, _drv_err_,
445 ("%s: next pkt len(%p,%d) exceed ptail(%p)!\n",
446 __FUNCTION__, ptr, pkt_offset, precvbuf->ptail));
447 rtw_free_recvframe(precvframe, &precvpriv->free_recv_queue);
452 if ((pattrib->crc_err) || (pattrib->icv_err))
454 #ifdef CONFIG_MP_INCLUDED
455 if (padapter->registrypriv.mp_mode == 1)
457 if ((check_fwstate(&padapter->mlmepriv, WIFI_MP_STATE) == _TRUE))//&&(padapter->mppriv.check_mp_pkt == 0))
459 if (pattrib->crc_err == 1)
460 padapter->mppriv.rx_crcerrpktcount++;
466 DBG_8192C("%s: crc_err=%d icv_err=%d, skip!\n", __FUNCTION__, pattrib->crc_err, pattrib->icv_err);
468 rtw_free_recvframe(precvframe, &precvpriv->free_recv_queue);
472 ppkt = rtw_skb_clone(precvbuf->pskb);
474 DBG_8192C("%s: no enough memory to allocate SKB!\n", __FUNCTION__);
475 rtw_free_recvframe(precvframe, &precvpriv->free_recv_queue);
476 rtw_enqueue_recvbuf_to_head(precvbuf, &precvpriv->recv_buf_pending_queue);
478 // The case of can't allocte skb is serious and may never be recovered,
479 // once bDriverStopped is enable, this task should be stopped.
480 if (padapter->bDriverStopped == _FALSE) {
481 #ifdef PLATFORM_LINUX
482 tasklet_schedule(&precvpriv->recv_tasklet);
491 phdr->rx_head = precvbuf->phead;
492 phdr->rx_data = phdr->rx_tail = precvbuf->pdata;
493 phdr->rx_end = precvbuf->pend;
494 recvframe_put(precvframe, pkt_offset);
495 recvframe_pull(precvframe, RXDESC_SIZE + pattrib->drvinfo_sz);
496 if (pHalData->ReceiveConfig & RCR_APPFCS)
497 recvframe_pull_tail(precvframe, IEEE80211_FCS_LEN);
499 // move to drv info position
503 if (pHalData->ReceiveConfig & RCR_APP_BA_SSN) {
504 //rtl8723s_update_bassn(padapter, pdrvinfo);
508 if (pattrib->pkt_rpt_type == NORMAL_RX) {
509 #ifdef CONFIG_CONCURRENT_MODE
510 if (rtw_buddy_adapter_up(padapter))
512 if (pre_recv_entry(precvframe, precvbuf, (struct phy_stat*)ptr) != _SUCCESS) {
513 DBG_8192C(FUNC_ADPT_FMT ": pre_recv_entry(precvframe) != _SUCCESS\n",
514 FUNC_ADPT_ARG(padapter->pbuddy_adapter));
519 rtl8723b_query_rx_phy_status(precvframe, (struct phy_stat*)ptr);
521 if (rtw_recv_entry(precvframe) != _SUCCESS)
523 RT_TRACE(_module_rtl871x_recv_c_, _drv_info_, ("rtl8723bs_recv_tasklet: rtw_recv_entry(precvframe) != _SUCCESS\n"));
527 #ifdef CONFIG_C2H_PACKET_EN
528 if (pattrib->pkt_rpt_type == C2H_PACKET) {
529 rtl8723b_c2h_packet_handler(padapter, precvframe->u.hdr.rx_data, pattrib->pkt_len);
532 DBG_8192C("%s: [WARNNING] RX type(%d) not be handled!\n",
533 __FUNCTION__, pattrib->pkt_rpt_type);
536 rtw_free_recvframe(precvframe, &precvpriv->free_recv_queue);
540 pkt_offset = _RND8(pkt_offset);
541 precvbuf->pdata += pkt_offset;
542 ptr = precvbuf->pdata;
545 rtw_skb_free(precvbuf->pskb);
546 precvbuf->pskb = NULL;
547 rtw_enqueue_recvbuf(precvbuf, &precvpriv->free_recv_buf_queue);
553 * Initialize recv private variable for hardware dependent
558 s32 rtl8723bs_init_recv_priv(PADAPTER padapter)
562 struct recv_priv *precvpriv;
563 struct recv_buf *precvbuf;
567 precvpriv = &padapter->recvpriv;
569 //3 1. init recv buffer
570 _rtw_init_queue(&precvpriv->free_recv_buf_queue);
571 _rtw_init_queue(&precvpriv->recv_buf_pending_queue);
573 n = NR_RECVBUFF * sizeof(struct recv_buf) + 4;
574 precvpriv->pallocated_recv_buf = rtw_zmalloc(n);
575 if (precvpriv->pallocated_recv_buf == NULL) {
577 RT_TRACE(_module_rtl871x_recv_c_, _drv_err_, ("alloc recv_buf fail!\n"));
581 precvpriv->precv_buf = (u8*)N_BYTE_ALIGMENT((SIZE_PTR)(precvpriv->pallocated_recv_buf), 4);
583 // init each recv buffer
584 precvbuf = (struct recv_buf*)precvpriv->precv_buf;
585 for (i = 0; i < NR_RECVBUFF; i++)
587 res = initrecvbuf(precvbuf, padapter);
591 res = rtw_os_recvbuf_resource_alloc(padapter, precvbuf);
593 freerecvbuf(precvbuf);
597 #ifdef CONFIG_SDIO_RX_COPY
598 if (precvbuf->pskb == NULL) {
600 SIZE_PTR alignment=0;
602 precvbuf->pskb = rtw_skb_alloc(MAX_RECVBUF_SZ + RECVBUFF_ALIGN_SZ);
606 precvbuf->pskb->dev = padapter->pnetdev;
608 tmpaddr = (SIZE_PTR)precvbuf->pskb->data;
609 alignment = tmpaddr & (RECVBUFF_ALIGN_SZ-1);
610 skb_reserve(precvbuf->pskb, (RECVBUFF_ALIGN_SZ - alignment));
613 if (precvbuf->pskb == NULL) {
614 DBG_871X("%s: alloc_skb fail!\n", __FUNCTION__);
619 rtw_list_insert_tail(&precvbuf->list, &precvpriv->free_recv_buf_queue.queue);
623 precvpriv->free_recv_buf_queue_cnt = i;
629 #ifdef PLATFORM_LINUX
630 tasklet_init(&precvpriv->recv_tasklet,
631 (void(*)(unsigned long))rtl8723bs_recv_tasklet,
632 (unsigned long)padapter);
638 precvbuf = (struct recv_buf*)precvpriv->precv_buf;
640 n = precvpriv->free_recv_buf_queue_cnt;
641 precvpriv->free_recv_buf_queue_cnt = 0;
642 for (i = 0; i < n ; i++)
644 rtw_list_delete(&precvbuf->list);
645 rtw_os_recvbuf_resource_free(padapter, precvbuf);
646 freerecvbuf(precvbuf);
649 precvpriv->precv_buf = NULL;
652 if (precvpriv->pallocated_recv_buf) {
653 n = NR_RECVBUFF * sizeof(struct recv_buf) + 4;
654 rtw_mfree(precvpriv->pallocated_recv_buf, n);
655 precvpriv->pallocated_recv_buf = NULL;
663 * Free recv private variable of hardware dependent
668 void rtl8723bs_free_recv_priv(PADAPTER padapter)
671 struct recv_priv *precvpriv;
672 struct recv_buf *precvbuf;
675 precvpriv = &padapter->recvpriv;
678 #ifdef PLATFORM_LINUX
679 tasklet_kill(&precvpriv->recv_tasklet);
682 //3 2. free all recv buffers
683 precvbuf = (struct recv_buf*)precvpriv->precv_buf;
686 precvpriv->free_recv_buf_queue_cnt = 0;
687 for (i = 0; i < n ; i++)
689 rtw_list_delete(&precvbuf->list);
690 rtw_os_recvbuf_resource_free(padapter, precvbuf);
691 freerecvbuf(precvbuf);
694 precvpriv->precv_buf = NULL;
697 if (precvpriv->pallocated_recv_buf) {
698 n = NR_RECVBUFF * sizeof(struct recv_buf) + 4;
699 rtw_mfree(precvpriv->pallocated_recv_buf, n);
700 precvpriv->pallocated_recv_buf = NULL;