OSDN Git Service

Remove another set of unecessary typedefs
[android-x86/external-modules-rtl8723au.git] / core / rtw_recv.c
1 /******************************************************************************
2  *
3  * Copyright(c) 2007 - 2012 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 _RTW_RECV_C_
21 #include <drv_conf.h>
22 #include <osdep_service.h>
23 #include <drv_types.h>
24 #include <recv_osdep.h>
25 #include <mlme_osdep.h>
26 #include <ip.h>
27 #include <if_ether.h>
28 #include <ethernet.h>
29
30 #ifdef CONFIG_USB_HCI
31 #include <usb_ops.h>
32 #endif
33
34 #include <wifi.h>
35 #include <circ_buf.h>
36
37 #ifdef CONFIG_NEW_SIGNAL_STAT_PROCESS
38 void rtw_signal_stat_timer_hdl(RTW_TIMER_HDL_ARGS);
39 #endif /* CONFIG_NEW_SIGNAL_STAT_PROCESS */
40
41 void _rtw_init_sta_recv_priv(struct sta_recv_priv *psta_recvpriv)
42 {
43
44 _func_enter_;
45
46         memset((u8 *)psta_recvpriv, 0, sizeof (struct sta_recv_priv));
47
48         spin_lock_init(&psta_recvpriv->lock);
49
50         /* for(i=0; i<MAX_RX_NUMBLKS; i++) */
51         /*      _rtw_init_queue(&psta_recvpriv->blk_strms[i]); */
52
53         _rtw_init_queue(&psta_recvpriv->defrag_q);
54
55 _func_exit_;
56 }
57
58 int _rtw_init_recv_priv(struct recv_priv *precvpriv, _adapter *padapter)
59 {
60         int i;
61
62         union recv_frame *precvframe;
63
64         int     res=_SUCCESS;
65
66 _func_enter_;
67
68         /*  We don't need to memset padapter->XXX to zero, because adapter is allocated by rtw_zvmalloc(). */
69         /* memset((unsigned char *)precvpriv, 0, sizeof (struct  recv_priv)); */
70
71         spin_lock_init(&precvpriv->lock);
72
73         _rtw_init_queue(&precvpriv->free_recv_queue);
74         _rtw_init_queue(&precvpriv->recv_pending_queue);
75         _rtw_init_queue(&precvpriv->uc_swdec_pending_queue);
76
77         precvpriv->adapter = padapter;
78
79         precvpriv->free_recvframe_cnt = NR_RECVFRAME;
80
81         rtw_os_recv_resource_init(precvpriv, padapter);
82
83         precvpriv->pallocated_frame_buf = rtw_zvmalloc(NR_RECVFRAME * sizeof(union recv_frame) + RXFRAME_ALIGN_SZ);
84
85         if(precvpriv->pallocated_frame_buf==NULL){
86                 res= _FAIL;
87                 goto exit;
88         }
89         /* memset(precvpriv->pallocated_frame_buf, 0, NR_RECVFRAME * sizeof(union recv_frame) + RXFRAME_ALIGN_SZ); */
90
91         precvpriv->precv_frame_buf = PTR_ALIGN(precvpriv->pallocated_frame_buf, RXFRAME_ALIGN_SZ);
92
93         precvframe = (union recv_frame*) precvpriv->precv_frame_buf;
94
95         for(i=0; i < NR_RECVFRAME ; i++)
96         {
97                 _rtw_init_listhead(&(precvframe->u.list));
98
99                 rtw_list_insert_tail(&(precvframe->u.list), &(precvpriv->free_recv_queue.queue));
100
101                 res = rtw_os_recv_resource_alloc(padapter, precvframe);
102
103                 precvframe->u.hdr.len = 0;
104
105                 precvframe->u.hdr.adapter =padapter;
106                 precvframe++;
107
108         }
109
110 #ifdef CONFIG_USB_HCI
111
112         precvpriv->rx_pending_cnt=1;
113
114         sema_init(&precvpriv->allrxreturnevt, 0);
115
116 #endif
117
118         res = rtw_hal_init_recv_priv(padapter);
119
120 #ifdef CONFIG_NEW_SIGNAL_STAT_PROCESS
121         _init_timer(&precvpriv->signal_stat_timer, padapter->pnetdev, RTW_TIMER_HDL_NAME(signal_stat), padapter);
122
123         precvpriv->signal_stat_sampling_interval = 1000; /* ms */
124
125         rtw_set_signal_stat_timer(precvpriv);
126 #endif /* CONFIG_NEW_SIGNAL_STAT_PROCESS */
127
128 exit:
129
130 _func_exit_;
131
132         return res;
133 }
134
135 void _rtw_free_recv_priv (struct recv_priv *precvpriv)
136 {
137         _adapter        *padapter = precvpriv->adapter;
138
139 _func_enter_;
140
141         rtw_free_uc_swdec_pending_queue(padapter);
142
143         rtw_os_recv_resource_free(precvpriv);
144
145         if(precvpriv->pallocated_frame_buf) {
146                 rtw_vmfree(precvpriv->pallocated_frame_buf, NR_RECVFRAME * sizeof(union recv_frame) + RXFRAME_ALIGN_SZ);
147         }
148
149         rtw_hal_free_recv_priv(padapter);
150
151 _func_exit_;
152 }
153
154 union recv_frame *_rtw_alloc_recvframe (_queue *pfree_recv_queue)
155 {
156
157         union recv_frame  *precvframe;
158         _list   *plist, *phead;
159         _adapter *padapter;
160         struct recv_priv *precvpriv;
161 _func_enter_;
162
163         if(_rtw_queue_empty(pfree_recv_queue) == _TRUE)
164         {
165                 precvframe = NULL;
166         }
167         else
168         {
169                 phead = get_list_head(pfree_recv_queue);
170
171                 plist = get_next(phead);
172
173                 precvframe = LIST_CONTAINOR(plist, union recv_frame, u);
174
175                 rtw_list_delete(&precvframe->u.hdr.list);
176                 padapter=precvframe->u.hdr.adapter;
177                 if(padapter !=NULL){
178                         precvpriv=&padapter->recvpriv;
179                         if(pfree_recv_queue == &precvpriv->free_recv_queue)
180                                 precvpriv->free_recvframe_cnt--;
181                 }
182         }
183
184 _func_exit_;
185
186         return precvframe;
187 }
188
189 union recv_frame *rtw_alloc_recvframe (_queue *pfree_recv_queue)
190 {
191         _irqL irqL;
192         union recv_frame  *precvframe;
193
194         spin_lock_bh(&pfree_recv_queue->lock);
195
196         precvframe = _rtw_alloc_recvframe(pfree_recv_queue);
197
198         spin_unlock_bh(&pfree_recv_queue->lock);
199
200         return precvframe;
201 }
202
203 void rtw_init_recvframe(union recv_frame *precvframe, struct recv_priv *precvpriv)
204 {
205         /* Perry: This can be removed */
206         _rtw_init_listhead(&precvframe->u.hdr.list);
207
208         precvframe->u.hdr.len=0;
209 }
210
211 int rtw_free_recvframe(union recv_frame *precvframe, _queue *pfree_recv_queue)
212 {
213         _irqL irqL;
214         _adapter *padapter=precvframe->u.hdr.adapter;
215         struct recv_priv *precvpriv = &padapter->recvpriv;
216
217 _func_enter_;
218
219 #ifdef CONFIG_CONCURRENT_MODE
220         if(padapter->adapter_type > PRIMARY_ADAPTER)
221         {
222                 padapter = padapter->pbuddy_adapter;/* get primary_padapter */
223                 precvpriv = &padapter->recvpriv;
224                 pfree_recv_queue = &precvpriv->free_recv_queue;
225                 precvframe->u.hdr.adapter = padapter;
226         }
227 #endif
228
229         if(precvframe->u.hdr.pkt)
230         {
231 #ifdef CONFIG_BSD_RX_USE_MBUF
232                 m_freem(precvframe->u.hdr.pkt);
233 #else   /*  CONFIG_BSD_RX_USE_MBUF */
234                 dev_kfree_skb_any(precvframe->u.hdr.pkt);/* free skb by driver */
235 #endif  /*  CONFIG_BSD_RX_USE_MBUF */
236                 precvframe->u.hdr.pkt = NULL;
237         }
238
239         spin_lock_bh(&pfree_recv_queue->lock);
240
241         rtw_list_delete(&(precvframe->u.hdr.list));
242
243         precvframe->u.hdr.len = 0;
244
245         rtw_list_insert_tail(&(precvframe->u.hdr.list), get_list_head(pfree_recv_queue));
246
247         if(padapter !=NULL){
248                 if(pfree_recv_queue == &precvpriv->free_recv_queue)
249                                 precvpriv->free_recvframe_cnt++;
250         }
251
252       spin_unlock_bh(&pfree_recv_queue->lock);
253
254 _func_exit_;
255
256         return _SUCCESS;
257 }
258
259 int _rtw_enqueue_recvframe(union recv_frame *precvframe, _queue *queue)
260 {
261
262         _adapter *padapter=precvframe->u.hdr.adapter;
263         struct recv_priv *precvpriv = &padapter->recvpriv;
264
265 _func_enter_;
266
267         /* _rtw_init_listhead(&(precvframe->u.hdr.list)); */
268         rtw_list_delete(&(precvframe->u.hdr.list));
269
270         rtw_list_insert_tail(&(precvframe->u.hdr.list), get_list_head(queue));
271
272         if (padapter != NULL) {
273                 if (queue == &precvpriv->free_recv_queue)
274                         precvpriv->free_recvframe_cnt++;
275         }
276
277 _func_exit_;
278
279         return _SUCCESS;
280 }
281
282 int rtw_enqueue_recvframe(union recv_frame *precvframe, _queue *queue)
283 {
284         int ret;
285         _irqL irqL;
286
287         /* _spinlock(&pfree_recv_queue->lock); */
288         spin_lock_bh(&queue->lock);
289         ret = _rtw_enqueue_recvframe(precvframe, queue);
290         /* spin_unlock(&pfree_recv_queue->lock); */
291         spin_unlock_bh(&queue->lock);
292
293         return ret;
294 }
295
296 /*
297 int     rtw_enqueue_recvframe(union recv_frame *precvframe, _queue *queue)
298 {
299         return rtw_free_recvframe(precvframe, queue);
300 }
301 */
302
303 /*
304 caller : defrag ; recvframe_chk_defrag in recv_thread  (passive)
305 pframequeue: defrag_queue : will be accessed in recv_thread  (passive)
306
307 using spinlock to protect
308
309 */
310
311 void rtw_free_recvframe_queue(_queue *pframequeue,  _queue *pfree_recv_queue)
312 {
313         union   recv_frame      *precvframe;
314         _list   *plist, *phead;
315
316 _func_enter_;
317         spin_lock(&pframequeue->lock);
318
319         phead = get_list_head(pframequeue);
320         plist = get_next(phead);
321
322         while(rtw_end_of_queue_search(phead, plist) == _FALSE) {
323                 precvframe = LIST_CONTAINOR(plist, union recv_frame, u);
324                 plist = get_next(plist);
325                 rtw_free_recvframe(precvframe, pfree_recv_queue);
326         }
327
328         spin_unlock(&pframequeue->lock);
329
330 _func_exit_;
331 }
332
333 u32 rtw_free_uc_swdec_pending_queue(_adapter *adapter)
334 {
335         u32 cnt = 0;
336         union recv_frame *pending_frame;
337         while((pending_frame=rtw_alloc_recvframe(&adapter->recvpriv.uc_swdec_pending_queue))) {
338                 rtw_free_recvframe(pending_frame, &adapter->recvpriv.free_recv_queue);
339                 DBG_8723A("%s: dequeue uc_swdec_pending_queue\n", __func__);
340                 cnt++;
341         }
342
343         return cnt;
344 }
345
346 int rtw_enqueue_recvbuf_to_head(struct recv_buf *precvbuf, _queue *queue)
347 {
348         _irqL irqL;
349
350         spin_lock_bh(&queue->lock);
351
352         rtw_list_delete(&precvbuf->list);
353         rtw_list_insert_head(&precvbuf->list, get_list_head(queue));
354
355         spin_unlock_bh(&queue->lock);
356
357         return _SUCCESS;
358 }
359
360 int rtw_enqueue_recvbuf(struct recv_buf *precvbuf, _queue *queue)
361 {
362         _irqL irqL;
363 #ifdef CONFIG_SDIO_HCI
364         spin_lock_bh(&queue->lock);
365 #else
366         spin_lock_irqsave(&queue->lock, irqL);
367 #endif/*#ifdef  CONFIG_SDIO_HCI*/
368
369         rtw_list_delete(&precvbuf->list);
370
371         rtw_list_insert_tail(&precvbuf->list, get_list_head(queue));
372 #ifdef CONFIG_SDIO_HCI
373         spin_unlock_bh(&queue->lock);
374 #else
375         spin_unlock_irqrestore(&queue->lock, irqL);
376 #endif/*#ifdef  CONFIG_SDIO_HCI*/
377         return _SUCCESS;
378 }
379
380 struct recv_buf *rtw_dequeue_recvbuf (_queue *queue)
381 {
382         _irqL irqL;
383         struct recv_buf *precvbuf;
384         _list   *plist, *phead;
385
386 #ifdef CONFIG_SDIO_HCI
387         spin_lock_bh(&queue->lock);
388 #else
389         spin_lock_irqsave(&queue->lock, irqL);
390 #endif/*#ifdef  CONFIG_SDIO_HCI*/
391
392         if(_rtw_queue_empty(queue) == _TRUE)
393         {
394                 precvbuf = NULL;
395         }
396         else
397         {
398                 phead = get_list_head(queue);
399
400                 plist = get_next(phead);
401
402                 precvbuf = LIST_CONTAINOR(plist, struct recv_buf, list);
403
404                 rtw_list_delete(&precvbuf->list);
405
406         }
407
408 #ifdef CONFIG_SDIO_HCI
409         spin_unlock_bh(&queue->lock);
410 #else
411         spin_unlock_irqrestore(&queue->lock, irqL);
412 #endif/*#ifdef  CONFIG_SDIO_HCI*/
413
414         return precvbuf;
415 }
416
417 int recvframe_chkmic(_adapter *adapter,  union recv_frame *precvframe);
418 int recvframe_chkmic(_adapter *adapter,  union recv_frame *precvframe){
419
420         int     i,res=_SUCCESS;
421         u32     datalen;
422         u8      miccode[8];
423         u8      bmic_err=_FALSE,brpt_micerror = _TRUE;
424         u8      *pframe, *payload,*pframemic;
425         u8      *mickey;
426         /* u8   *iv,rxdata_key_idx=0; */
427         struct  sta_info                *stainfo;
428         struct  rx_pkt_attrib   *prxattrib=&precvframe->u.hdr.attrib;
429         struct  security_priv   *psecuritypriv=&adapter->securitypriv;
430
431         struct mlme_ext_priv    *pmlmeext = &adapter->mlmeextpriv;
432         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);
433 _func_enter_;
434
435         stainfo=rtw_get_stainfo(&adapter->stapriv ,&prxattrib->ta[0]);
436
437         if(prxattrib->encrypt ==_TKIP_)
438         {
439                 RT_TRACE(_module_rtl871x_recv_c_,_drv_info_,("\n recvframe_chkmic:prxattrib->encrypt ==_TKIP_\n"));
440                 RT_TRACE(_module_rtl871x_recv_c_,_drv_info_,("\n recvframe_chkmic:da=0x%02x:0x%02x:0x%02x:0x%02x:0x%02x:0x%02x\n",
441                         prxattrib->ra[0],prxattrib->ra[1],prxattrib->ra[2],prxattrib->ra[3],prxattrib->ra[4],prxattrib->ra[5]));
442
443                 /* calculate mic code */
444                 if(stainfo!= NULL)
445                 {
446                         if(IS_MCAST(prxattrib->ra))
447                         {
448                                 mickey=&psecuritypriv->dot118021XGrprxmickey[prxattrib->key_index].skey[0];
449
450                                 RT_TRACE(_module_rtl871x_recv_c_,_drv_info_,("\n recvframe_chkmic: bcmc key \n"));
451
452                                 if(psecuritypriv->binstallGrpkey==_FALSE)
453                                 {
454                                         res=_FAIL;
455                                         RT_TRACE(_module_rtl871x_recv_c_,_drv_err_,("\n recvframe_chkmic:didn't install group key!!!!!!!!!!\n"));
456                                         DBG_8723A("\n recvframe_chkmic:didn't install group key!!!!!!!!!!\n");
457                                         goto exit;
458                                 }
459                         }
460                         else{
461                                 mickey=&stainfo->dot11tkiprxmickey.skey[0];
462                                 RT_TRACE(_module_rtl871x_recv_c_,_drv_err_,("\n recvframe_chkmic: unicast key \n"));
463                         }
464
465                         datalen=precvframe->u.hdr.len-prxattrib->hdrlen-prxattrib->iv_len-prxattrib->icv_len-8;/* icv_len included the mic code */
466                         pframe=precvframe->u.hdr.rx_data;
467                         payload=pframe+prxattrib->hdrlen+prxattrib->iv_len;
468
469                         RT_TRACE(_module_rtl871x_recv_c_,_drv_info_,("\n prxattrib->iv_len=%d prxattrib->icv_len=%d\n",prxattrib->iv_len,prxattrib->icv_len));
470
471                         rtw_seccalctkipmic(mickey,pframe,payload, datalen ,&miccode[0],(unsigned char)prxattrib->priority); /* care the length of the data */
472
473                         pframemic=payload+datalen;
474
475                         bmic_err=_FALSE;
476
477                         for(i=0;i<8;i++){
478                                 if(miccode[i] != *(pframemic+i)){
479                                         RT_TRACE(_module_rtl871x_recv_c_,_drv_err_,("recvframe_chkmic:miccode[%d](%02x) != *(pframemic+%d)(%02x) ",i,miccode[i],i,*(pframemic+i)));
480                                         bmic_err=_TRUE;
481                                 }
482                         }
483
484                         if(bmic_err==_TRUE){
485
486                                 RT_TRACE(_module_rtl871x_recv_c_,_drv_err_,("\n *(pframemic-8)-*(pframemic-1)=0x%02x:0x%02x:0x%02x:0x%02x:0x%02x:0x%02x:0x%02x:0x%02x\n",
487                                         *(pframemic-8),*(pframemic-7),*(pframemic-6),*(pframemic-5),*(pframemic-4),*(pframemic-3),*(pframemic-2),*(pframemic-1)));
488                                 RT_TRACE(_module_rtl871x_recv_c_,_drv_err_,("\n *(pframemic-16)-*(pframemic-9)=0x%02x:0x%02x:0x%02x:0x%02x:0x%02x:0x%02x:0x%02x:0x%02x\n",
489                                         *(pframemic-16),*(pframemic-15),*(pframemic-14),*(pframemic-13),*(pframemic-12),*(pframemic-11),*(pframemic-10),*(pframemic-9)));
490
491                                 {
492                                         uint i;
493                                         RT_TRACE(_module_rtl871x_recv_c_,_drv_err_,("\n ======demp packet (len=%d)======\n",precvframe->u.hdr.len));
494                                         for(i=0;i<precvframe->u.hdr.len;i=i+8){
495                                                 RT_TRACE(_module_rtl871x_recv_c_,_drv_err_,("0x%02x:0x%02x:0x%02x:0x%02x:0x%02x:0x%02x:0x%02x:0x%02x",
496                                                         *(precvframe->u.hdr.rx_data+i),*(precvframe->u.hdr.rx_data+i+1),
497                                                         *(precvframe->u.hdr.rx_data+i+2),*(precvframe->u.hdr.rx_data+i+3),
498                                                         *(precvframe->u.hdr.rx_data+i+4),*(precvframe->u.hdr.rx_data+i+5),
499                                                         *(precvframe->u.hdr.rx_data+i+6),*(precvframe->u.hdr.rx_data+i+7)));
500                                         }
501                                         RT_TRACE(_module_rtl871x_recv_c_,_drv_err_,("\n ======demp packet end [len=%d]======\n",precvframe->u.hdr.len));
502                                         RT_TRACE(_module_rtl871x_recv_c_,_drv_err_,("\n hrdlen=%d, \n",prxattrib->hdrlen));
503                                 }
504
505                                 RT_TRACE(_module_rtl871x_recv_c_,_drv_err_,("ra=0x%.2x 0x%.2x 0x%.2x 0x%.2x 0x%.2x 0x%.2x psecuritypriv->binstallGrpkey=%d ",
506                                         prxattrib->ra[0],prxattrib->ra[1],prxattrib->ra[2],
507                                         prxattrib->ra[3],prxattrib->ra[4],prxattrib->ra[5],psecuritypriv->binstallGrpkey));
508
509                                 /*  double check key_index for some timing issue , */
510                                 /*  cannot compare with psecuritypriv->dot118021XGrpKeyid also cause timing issue */
511                                 if((IS_MCAST(prxattrib->ra)==_TRUE)  && (prxattrib->key_index != pmlmeinfo->key_index ))
512                                         brpt_micerror = _FALSE;
513
514                                 if((prxattrib->bdecrypted ==_TRUE)&& (brpt_micerror == _TRUE))
515                                 {
516                                         rtw_handle_tkip_mic_err(adapter,(u8)IS_MCAST(prxattrib->ra));
517                                         RT_TRACE(_module_rtl871x_recv_c_,_drv_err_,(" mic error :prxattrib->bdecrypted=%d ",prxattrib->bdecrypted));
518                                         DBG_8723A(" mic error :prxattrib->bdecrypted=%d\n",prxattrib->bdecrypted);
519                                 }
520                                 else
521                                 {
522                                         RT_TRACE(_module_rtl871x_recv_c_,_drv_err_,(" mic error :prxattrib->bdecrypted=%d ",prxattrib->bdecrypted));
523                                         DBG_8723A(" mic error :prxattrib->bdecrypted=%d\n",prxattrib->bdecrypted);
524                                 }
525
526                                 res=_FAIL;
527
528                         }
529                         else{
530                                 /* mic checked ok */
531                                 if((psecuritypriv->bcheck_grpkey ==_FALSE)&&(IS_MCAST(prxattrib->ra)==_TRUE)){
532                                         psecuritypriv->bcheck_grpkey =_TRUE;
533                                         RT_TRACE(_module_rtl871x_recv_c_,_drv_err_,("psecuritypriv->bcheck_grpkey =_TRUE"));
534                                 }
535                         }
536
537                 }
538                 else
539                 {
540                         RT_TRACE(_module_rtl871x_recv_c_,_drv_err_,("recvframe_chkmic: rtw_get_stainfo==NULL!!!\n"));
541                 }
542
543                 recvframe_pull_tail(precvframe, 8);
544
545         }
546
547 exit:
548
549 _func_exit_;
550
551         return res;
552 }
553
554 /* decrypt and set the ivlen,icvlen of the recv_frame */
555 union recv_frame * decryptor(_adapter *padapter,union recv_frame *precv_frame);
556 union recv_frame * decryptor(_adapter *padapter,union recv_frame *precv_frame)
557 {
558
559         struct rx_pkt_attrib *prxattrib = &precv_frame->u.hdr.attrib;
560         struct security_priv *psecuritypriv=&padapter->securitypriv;
561         union recv_frame *return_packet=precv_frame;
562         u32      res=_SUCCESS;
563 _func_enter_;
564
565         RT_TRACE(_module_rtl871x_recv_c_,_drv_info_,("prxstat->decrypted=%x prxattrib->encrypt = 0x%03x\n",prxattrib->bdecrypted,prxattrib->encrypt));
566
567         if(prxattrib->encrypt>0)
568         {
569                 u8 *iv = precv_frame->u.hdr.rx_data+prxattrib->hdrlen;
570                 prxattrib->key_index = ( ((iv[3])>>6)&0x3) ;
571
572                 if(prxattrib->key_index > WEP_KEYS)
573                 {
574                         DBG_8723A("prxattrib->key_index(%d) > WEP_KEYS \n", prxattrib->key_index);
575
576                         switch(prxattrib->encrypt){
577                                 case _WEP40_:
578                                 case _WEP104_:
579                                         prxattrib->key_index = psecuritypriv->dot11PrivacyKeyIndex;
580                                         break;
581                                 case _TKIP_:
582                                 case _AES_:
583                                 default:
584                                         prxattrib->key_index = psecuritypriv->dot118021XGrpKeyid;
585                                         break;
586                         }
587                 }
588         }
589
590         if((prxattrib->encrypt>0) && ((prxattrib->bdecrypted==0) ||(psecuritypriv->sw_decrypt==_TRUE)))
591         {
592
593 #ifdef CONFIG_CONCURRENT_MODE
594                 if(!IS_MCAST(prxattrib->ra))/* bc/mc packets use sw decryption for concurrent mode */
595 #endif
596                 psecuritypriv->hw_decrypted=_FALSE;
597
598                 #ifdef DBG_RX_DECRYPTOR
599                 DBG_8723A("prxstat->bdecrypted:%d,  prxattrib->encrypt:%d,  Setting psecuritypriv->hw_decrypted = %d\n"
600                         , prxattrib->bdecrypted ,prxattrib->encrypt, psecuritypriv->hw_decrypted);
601                 #endif
602
603                 switch(prxattrib->encrypt){
604                 case _WEP40_:
605                 case _WEP104_:
606                         rtw_wep_decrypt(padapter, (u8 *)precv_frame);
607                         break;
608                 case _TKIP_:
609                         res = rtw_tkip_decrypt(padapter, (u8 *)precv_frame);
610                         break;
611                 case _AES_:
612                         res = rtw_aes_decrypt(padapter, (u8 * )precv_frame);
613                         break;
614 #ifdef CONFIG_WAPI_SUPPORT
615                 case _SMS4_:
616                         rtw_sms4_decrypt(padapter, (u8 * )precv_frame);
617                         break;
618 #endif
619                 default:
620                                 break;
621                 }
622         }
623         else if(prxattrib->bdecrypted==1
624                 && prxattrib->encrypt >0
625                 && (psecuritypriv->busetkipkey==1 || prxattrib->encrypt !=_TKIP_ )
626                 )
627         {
628                 {
629                         psecuritypriv->hw_decrypted=_TRUE;
630                         #ifdef DBG_RX_DECRYPTOR
631                         DBG_8723A("prxstat->bdecrypted:%d,  prxattrib->encrypt:%d,  Setting psecuritypriv->hw_decrypted = %d\n"
632                         , prxattrib->bdecrypted ,prxattrib->encrypt, psecuritypriv->hw_decrypted);
633                         #endif
634
635                 }
636         }
637         else {
638                 #ifdef DBG_RX_DECRYPTOR
639                 DBG_8723A("prxstat->bdecrypted:%d,  prxattrib->encrypt:%d,  psecuritypriv->hw_decrypted:%d\n"
640                 , prxattrib->bdecrypted ,prxattrib->encrypt, psecuritypriv->hw_decrypted);
641                 #endif
642         }
643
644         if(res == _FAIL)
645         {
646                 rtw_free_recvframe(return_packet,&padapter->recvpriv.free_recv_queue);
647                 return_packet = NULL;
648
649         }
650
651 _func_exit_;
652
653         return return_packet;
654 }
655 /* set the security information in the recv_frame */
656 union recv_frame * portctrl(_adapter *adapter,union recv_frame * precv_frame)
657 {
658         u8   *psta_addr, *ptr;
659         uint  auth_alg;
660         struct recv_frame_hdr *pfhdr;
661         struct sta_info *psta;
662         struct sta_priv *pstapriv ;
663         union recv_frame *prtnframe;
664         u16     ether_type=0;
665         u16  eapol_type = 0x888e;/* for Funia BD's WPA issue */
666         struct rx_pkt_attrib *pattrib;
667
668 _func_enter_;
669
670         pstapriv = &adapter->stapriv;
671         psta = rtw_get_stainfo(pstapriv, psta_addr);
672
673         auth_alg = adapter->securitypriv.dot11AuthAlgrthm;
674
675         ptr = get_recvframe_data(precv_frame);
676         pfhdr = &precv_frame->u.hdr;
677         pattrib = &pfhdr->attrib;
678         psta_addr = pattrib->ta;
679
680         prtnframe = NULL;
681
682         RT_TRACE(_module_rtl871x_recv_c_,_drv_info_,("########portctrl:adapter->securitypriv.dot11AuthAlgrthm=%d\n",adapter->securitypriv.dot11AuthAlgrthm));
683
684         if(auth_alg==2)
685         {
686                 if ((psta!=NULL) && (psta->ieee8021x_blocked))
687                 {
688                         /* blocked */
689                         /* only accept EAPOL frame */
690                         RT_TRACE(_module_rtl871x_recv_c_,_drv_info_,("########portctrl:psta->ieee8021x_blocked==1\n"));
691
692                         prtnframe=precv_frame;
693
694                         /* get ether_type */
695                         ptr=ptr+pfhdr->attrib.hdrlen+pfhdr->attrib.iv_len+LLC_HEADER_SIZE;
696                         memcpy(&ether_type,ptr, 2);
697                         ether_type= ntohs((unsigned short )ether_type);
698
699                         if (ether_type == eapol_type) {
700                                 prtnframe=precv_frame;
701                         }
702                         else {
703                                 /* free this frame */
704                                 rtw_free_recvframe(precv_frame, &adapter->recvpriv.free_recv_queue);
705                                 prtnframe=NULL;
706                         }
707                 }
708                 else
709                 {
710                         /* allowed */
711                         /* check decryption status, and decrypt the frame if needed */
712                         RT_TRACE(_module_rtl871x_recv_c_,_drv_info_,("########portctrl:psta->ieee8021x_blocked==0\n"));
713                         RT_TRACE(_module_rtl871x_recv_c_,_drv_info_,("portctrl:precv_frame->hdr.attrib.privacy=%x\n",precv_frame->u.hdr.attrib.privacy));
714
715                         if (pattrib->bdecrypted == 0)
716                         {
717                                 RT_TRACE(_module_rtl871x_recv_c_,_drv_info_,("portctrl:prxstat->decrypted=%x\n", pattrib->bdecrypted));
718                         }
719
720                         prtnframe=precv_frame;
721                         /* check is the EAPOL frame or not (Rekey) */
722                         if(ether_type == eapol_type){
723
724                                 RT_TRACE(_module_rtl871x_recv_c_,_drv_notice_,("########portctrl:ether_type == 0x888e\n"));
725                                 /* check Rekey */
726
727                                 prtnframe=precv_frame;
728                         }
729                         else{
730                                 RT_TRACE(_module_rtl871x_recv_c_,_drv_info_,("########portctrl:ether_type=0x%04x\n", ether_type));
731                         }
732                 }
733         }
734         else
735         {
736                 prtnframe=precv_frame;
737         }
738
739 _func_exit_;
740
741                 return prtnframe;
742 }
743
744 int recv_decache(union recv_frame *precv_frame, u8 bretry, struct stainfo_rxcache *prxcache);
745 int recv_decache(union recv_frame *precv_frame, u8 bretry, struct stainfo_rxcache *prxcache)
746 {
747         int tid = precv_frame->u.hdr.attrib.priority;
748
749         u16 seq_ctrl = ( (precv_frame->u.hdr.attrib.seq_num&0xffff) << 4) |
750                 (precv_frame->u.hdr.attrib.frag_num & 0xf);
751
752 _func_enter_;
753
754         if(tid>15)
755         {
756                 RT_TRACE(_module_rtl871x_recv_c_, _drv_notice_, ("recv_decache, (tid>15)! seq_ctrl=0x%x, tid=0x%x\n", seq_ctrl, tid));
757
758                 return _FAIL;
759         }
760
761         if(1)/* if(bretry) */
762         {
763                 if(seq_ctrl == prxcache->tid_rxseq[tid])
764                 {
765                         RT_TRACE(_module_rtl871x_recv_c_, _drv_notice_, ("recv_decache, seq_ctrl=0x%x, tid=0x%x, tid_rxseq=0x%x\n", seq_ctrl, tid, prxcache->tid_rxseq[tid]));
766
767                         return _FAIL;
768                 }
769         }
770
771         prxcache->tid_rxseq[tid] = seq_ctrl;
772
773 _func_exit_;
774
775         return _SUCCESS;
776 }
777
778 void process_pwrbit_data(_adapter *padapter, union recv_frame *precv_frame);
779 void process_pwrbit_data(_adapter *padapter, union recv_frame *precv_frame)
780 {
781 #ifdef CONFIG_AP_MODE
782         unsigned char pwrbit;
783         u8 *ptr = precv_frame->u.hdr.rx_data;
784         struct rx_pkt_attrib *pattrib = &precv_frame->u.hdr.attrib;
785         struct sta_priv *pstapriv = &padapter->stapriv;
786         struct sta_info *psta=NULL;
787
788         psta = rtw_get_stainfo(pstapriv, pattrib->src);
789
790         pwrbit = GetPwrMgt(ptr);
791
792         if(psta)
793         {
794                 if(pwrbit)
795                 {
796                         if(!(psta->state & WIFI_SLEEP_STATE))
797                         {
798                                 /* psta->state |= WIFI_SLEEP_STATE; */
799                                 /* pstapriv->sta_dz_bitmap |= BIT(psta->aid); */
800
801                                 stop_sta_xmit(padapter, psta);
802
803                                 /* DBG_8723A("to sleep, sta_dz_bitmap=%x\n", pstapriv->sta_dz_bitmap); */
804                         }
805                 }
806                 else
807                 {
808                         if(psta->state & WIFI_SLEEP_STATE)
809                         {
810                                 /* psta->state ^= WIFI_SLEEP_STATE; */
811                                 /* pstapriv->sta_dz_bitmap &= ~BIT(psta->aid); */
812
813                                 wakeup_sta_to_xmit(padapter, psta);
814
815                                 /* DBG_8723A("to wakeup, sta_dz_bitmap=%x\n", pstapriv->sta_dz_bitmap); */
816                         }
817                 }
818
819         }
820
821 #endif
822 }
823
824 void process_wmmps_data(_adapter *padapter, union recv_frame *precv_frame);
825 void process_wmmps_data(_adapter *padapter, union recv_frame *precv_frame)
826 {
827 #ifdef CONFIG_AP_MODE
828         struct rx_pkt_attrib *pattrib = &precv_frame->u.hdr.attrib;
829         struct sta_priv *pstapriv = &padapter->stapriv;
830         struct sta_info *psta=NULL;
831
832         psta = rtw_get_stainfo(pstapriv, pattrib->src);
833
834         if(!psta) return;
835
836 #ifdef CONFIG_TDLS
837         if( !(psta->tdls_sta_state & TDLS_LINKED_STATE ) )
838         {
839 #endif /* CONFIG_TDLS */
840
841         if(!psta->qos_option)
842                 return;
843
844         if(!(psta->qos_info&0xf))
845                 return;
846
847 #ifdef CONFIG_TDLS
848         }
849 #endif /* CONFIG_TDLS */
850
851         if(psta->state&WIFI_SLEEP_STATE)
852         {
853                 u8 wmmps_ac=0;
854
855                 switch(pattrib->priority)
856                 {
857                         case 1:
858                         case 2:
859                                 wmmps_ac = psta->uapsd_bk&BIT(1);
860                                 break;
861                         case 4:
862                         case 5:
863                                 wmmps_ac = psta->uapsd_vi&BIT(1);
864                                 break;
865                         case 6:
866                         case 7:
867                                 wmmps_ac = psta->uapsd_vo&BIT(1);
868                                 break;
869                         case 0:
870                         case 3:
871                         default:
872                                 wmmps_ac = psta->uapsd_be&BIT(1);
873                                 break;
874                 }
875
876                 if(wmmps_ac)
877                 {
878                         if(psta->sleepq_ac_len>0)
879                         {
880                                 /* process received triggered frame */
881                                 xmit_delivery_enabled_frames(padapter, psta);
882                         }
883                         else
884                         {
885                                 /* issue one qos null frame with More data bit = 0 and the EOSP bit set (=1) */
886                                 issue_qos_nulldata(padapter, psta->hwaddr, (u16)pattrib->priority, 0, 0);
887                         }
888                 }
889
890         }
891
892 #endif
893 }
894
895 #ifdef CONFIG_TDLS
896 int OnTDLS(_adapter *adapter, union recv_frame *precv_frame)
897 {
898         struct rx_pkt_attrib    *pattrib = & precv_frame->u.hdr.attrib;
899         int ret = _SUCCESS;
900         u8 *paction = get_recvframe_data(precv_frame);
901         u8 category_field = 1;
902 #ifdef CONFIG_WFD
903         u8 WFA_OUI[3] = { 0x50, 0x6f, 0x9a };
904 #endif /* CONFIG_WFD */
905         struct tdls_info *ptdlsinfo = &(adapter->tdlsinfo);
906
907         /* point to action field */
908         paction+=pattrib->hdrlen
909                         + pattrib->iv_len
910                         + SNAP_SIZE
911                         + ETH_TYPE_LEN
912                         + PAYLOAD_TYPE_LEN
913                         + category_field;
914
915         if(ptdlsinfo->enable == 0)
916         {
917                 DBG_8723A("recv tdls frame, "
918                                 "but tdls haven't enabled\n");
919                 ret = _FAIL;
920                 return ret;
921         }
922
923         switch(*paction){
924                 case TDLS_SETUP_REQUEST:
925                         DBG_8723A("recv tdls setup request frame\n");
926                         ret=On_TDLS_Setup_Req(adapter, precv_frame);
927                         break;
928                 case TDLS_SETUP_RESPONSE:
929                         DBG_8723A("recv tdls setup response frame\n");
930                         ret=On_TDLS_Setup_Rsp(adapter, precv_frame);
931                         break;
932                 case TDLS_SETUP_CONFIRM:
933                         DBG_8723A("recv tdls setup confirm frame\n");
934                         ret=On_TDLS_Setup_Cfm(adapter, precv_frame);
935                         break;
936                 case TDLS_TEARDOWN:
937                         DBG_8723A("recv tdls teardown, free sta_info\n");
938                         ret=On_TDLS_Teardown(adapter, precv_frame);
939                         break;
940                 case TDLS_DISCOVERY_REQUEST:
941                         DBG_8723A("recv tdls discovery request frame\n");
942                         ret=On_TDLS_Dis_Req(adapter, precv_frame);
943                         break;
944                 case TDLS_PEER_TRAFFIC_RESPONSE:
945                         DBG_8723A("recv tdls peer traffic response frame\n");
946                         ret=On_TDLS_Peer_Traffic_Rsp(adapter, precv_frame);
947                         break;
948                 case TDLS_CHANNEL_SWITCH_REQUEST:
949                         DBG_8723A("recv tdls channel switch request frame\n");
950                         ret=On_TDLS_Ch_Switch_Req(adapter, precv_frame);
951                         break;
952                 case TDLS_CHANNEL_SWITCH_RESPONSE:
953                         DBG_8723A("recv tdls channel switch response frame\n");
954                         ret=On_TDLS_Ch_Switch_Rsp(adapter, precv_frame);
955                         break;
956 #ifdef CONFIG_WFD
957                 case 0x50:      /* First byte of WFA OUI */
958                         if (!memcmp(WFA_OUI, (paction), 3))
959                         {
960                                 if( *(paction + 3) == 0x04)     /* Probe request frame */
961                                 {
962                                         /* WFDTDLS: for sigma test, do not setup direct link automatically */
963                                         ptdlsinfo->dev_discovered = 1;
964                                         DBG_8723A("recv tunneled probe request frame\n");
965                                         issue_tunneled_probe_rsp(adapter, precv_frame);
966                                 }
967                                 if( *(paction + 3) == 0x05)     /* Probe response frame */
968                                 {
969                                         /* WFDTDLS: for sigma test, do not setup direct link automatically */
970                                         ptdlsinfo->dev_discovered = 1;
971                                         DBG_8723A("recv tunneled probe response frame\n");
972                                 }
973                         }
974                         break;
975 #endif /* CONFIG_WFD */
976                 default:
977                         DBG_8723A("receive TDLS frame but not supported\n");
978                         ret=_FAIL;
979                         break;
980         }
981
982 exit:
983         return ret;
984 }
985 #endif
986
987 void count_rx_stats(_adapter *padapter, union recv_frame *prframe, struct sta_info*sta);
988 void count_rx_stats(_adapter *padapter, union recv_frame *prframe, struct sta_info*sta)
989 {
990         int     sz;
991         struct sta_info         *psta = NULL;
992         struct stainfo_stats    *pstats = NULL;
993         struct rx_pkt_attrib    *pattrib = & prframe->u.hdr.attrib;
994         struct recv_priv                *precvpriv = &padapter->recvpriv;
995
996         sz = get_recvframe_len(prframe);
997         precvpriv->rx_bytes += sz;
998
999         padapter->mlmepriv.LinkDetectInfo.NumRxOkInPeriod++;
1000
1001         if( (!MacAddr_isBcst(pattrib->dst)) && (!IS_MCAST(pattrib->dst))){
1002                 padapter->mlmepriv.LinkDetectInfo.NumRxUnicastOkInPeriod++;
1003         }
1004
1005         if(sta)
1006                 psta = sta;
1007         else
1008                 psta = prframe->u.hdr.psta;
1009
1010         if(psta)
1011         {
1012                 pstats = &psta->sta_stats;
1013
1014                 pstats->rx_data_pkts++;
1015                 pstats->rx_bytes += sz;
1016         }
1017 }
1018
1019 int sta2sta_data_frame(
1020         _adapter *adapter,
1021         union recv_frame *precv_frame,
1022         struct sta_info**psta
1023 );
1024 int sta2sta_data_frame(
1025         _adapter *adapter,
1026         union recv_frame *precv_frame,
1027         struct sta_info**psta
1028 )
1029 {
1030         u8 *ptr = precv_frame->u.hdr.rx_data;
1031         int ret = _SUCCESS;
1032         struct rx_pkt_attrib *pattrib = & precv_frame->u.hdr.attrib;
1033         struct  sta_priv                *pstapriv = &adapter->stapriv;
1034         struct  mlme_priv       *pmlmepriv = &adapter->mlmepriv;
1035         u8 *mybssid  = get_bssid(pmlmepriv);
1036         u8 *myhwaddr = myid(&adapter->eeprompriv);
1037         u8 * sta_addr = NULL;
1038         int bmcast = IS_MCAST(pattrib->dst);
1039
1040 #ifdef CONFIG_TDLS
1041         struct tdls_info *ptdlsinfo = &adapter->tdlsinfo;
1042         struct sta_info *ptdls_sta=NULL;
1043         u8 *psnap_type=ptr+pattrib->hdrlen + pattrib->iv_len+SNAP_SIZE;
1044         /* frame body located after [+2]: ether-type, [+1]: payload type */
1045         u8 *pframe_body = psnap_type+2+1;
1046 #endif
1047
1048 _func_enter_;
1049
1050         if ((check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) == _TRUE) ||
1051                 (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) == _TRUE))
1052         {
1053
1054                 /*  filter packets that SA is myself or multicast or broadcast */
1055                 if (!memcmp(myhwaddr, pattrib->src, ETH_ALEN)) {
1056                         RT_TRACE(_module_rtl871x_recv_c_,_drv_err_,(" SA==myself \n"));
1057                         ret= _FAIL;
1058                         goto exit;
1059                 }
1060
1061                 if ((memcmp(myhwaddr, pattrib->dst, ETH_ALEN)) && (!bmcast)) {
1062                         ret= _FAIL;
1063                         goto exit;
1064                 }
1065
1066                 if (!memcmp(pattrib->bssid, "\x0\x0\x0\x0\x0\x0", ETH_ALEN) ||
1067                     !memcmp(mybssid, "\x0\x0\x0\x0\x0\x0", ETH_ALEN) ||
1068                     memcmp(pattrib->bssid, mybssid, ETH_ALEN)) {
1069                         ret= _FAIL;
1070                         goto exit;
1071                 }
1072
1073                 sta_addr = pattrib->src;
1074
1075         }
1076         else if(check_fwstate(pmlmepriv, WIFI_STATION_STATE) == _TRUE)
1077         {
1078 #ifdef CONFIG_TDLS
1079
1080                 /* direct link data transfer */
1081                 if(ptdlsinfo->setup_state == TDLS_LINKED_STATE){
1082                         ptdls_sta = rtw_get_stainfo(pstapriv, pattrib->src);
1083                         if(ptdls_sta==NULL)
1084                         {
1085                                 ret=_FAIL;
1086                                 goto exit;
1087                         }
1088                         else if(ptdls_sta->tdls_sta_state&TDLS_LINKED_STATE)
1089                         {
1090
1091                                 /* drop QoS-SubType Data, including QoS NULL, excluding QoS-Data */
1092                                 if( (GetFrameSubType(ptr) & WIFI_QOS_DATA_TYPE )== WIFI_QOS_DATA_TYPE)
1093                                 {
1094                                         if(GetFrameSubType(ptr)&(BIT(4)|BIT(5)|BIT(6)))
1095                                         {
1096                                                 DBG_8723A("drop QoS-Sybtype Data\n");
1097                                         ret= _FAIL;
1098                                         goto exit;
1099                                         }
1100                                 }
1101                                 /*  filter packets that SA is myself or multicast or broadcast */
1102                                 if (!memcmp(myhwaddr, pattrib->src, ETH_ALEN)){
1103                                         ret= _FAIL;
1104                                         goto exit;
1105                                 }
1106                                 /*  da should be for me */
1107                                 if ((memcmp(myhwaddr, pattrib->dst, ETH_ALEN))&& (!bmcast))
1108                                 {
1109                                         ret= _FAIL;
1110                                         goto exit;
1111                                 }
1112                                 /*  check BSSID */
1113                                 if (!memcmp(pattrib->bssid, "\x0\x0\x0\x0\x0\x0", ETH_ALEN) ||
1114                                     !memcmp(mybssid, "\x0\x0\x0\x0\x0\x0", ETH_ALEN) ||
1115                                     memcmp(pattrib->bssid, mybssid, ETH_ALEN)) {
1116                                         ret= _FAIL;
1117                                         goto exit;
1118                                 }
1119
1120                                 /* process UAPSD tdls sta */
1121                                 process_pwrbit_data(adapter, precv_frame);
1122
1123                                 /*  if NULL-frame, check pwrbit */
1124                                 if ((GetFrameSubType(ptr)) == WIFI_DATA_NULL)
1125                                 {
1126                                         /* NULL-frame with pwrbit=1, buffer_STA should buffer frames for sleep_STA */
1127                                         if(GetPwrMgt(ptr))
1128                                         {
1129                                                 DBG_8723A("TDLS: recv peer null frame with pwr bit 1\n");
1130                                                 ptdls_sta->tdls_sta_state|=TDLS_PEER_SLEEP_STATE;
1131                                         /*  it would be triggered when we are off channel and receiving NULL DATA */
1132                                         /*  we can confirm that peer STA is at off channel */
1133                                         }
1134                                         else if(ptdls_sta->tdls_sta_state&TDLS_CH_SWITCH_ON_STATE)
1135                                         {
1136                                                 if((ptdls_sta->tdls_sta_state & TDLS_PEER_AT_OFF_STATE) != TDLS_PEER_AT_OFF_STATE)
1137                                                 {
1138                                                         issue_nulldata_to_TDLS_peer_STA(adapter, ptdls_sta, 0);
1139                                                         ptdls_sta->tdls_sta_state |= TDLS_PEER_AT_OFF_STATE;
1140                                                         On_TDLS_Peer_Traffic_Rsp(adapter, precv_frame);
1141                                                 }
1142                                         }
1143
1144                                         ret= _FAIL;
1145                                         goto exit;
1146                                 }
1147                                 /* receive some of all TDLS management frames, process it at ON_TDLS */
1148                                 if (!memcmp(psnap_type, SNAP_ETH_TYPE_TDLS, 2)){
1149                                         ret = OnTDLS(adapter, precv_frame);
1150                                         goto exit;
1151                                 }
1152
1153                         }
1154
1155                         sta_addr = pattrib->src;
1156
1157                 }
1158                 else
1159 #endif /* CONFIG_TDLS */
1160                 {
1161                         /*  For Station mode, sa and bssid should always be BSSID, and DA is my mac-address */
1162                         if (memcmp(pattrib->bssid, pattrib->src, ETH_ALEN))
1163                         {
1164                                 RT_TRACE(_module_rtl871x_recv_c_,_drv_err_,("bssid != TA under STATION_MODE; drop pkt\n"));
1165                                 ret= _FAIL;
1166                                 goto exit;
1167                 }
1168
1169                 sta_addr = pattrib->bssid;
1170                 }
1171
1172         }
1173         else if(check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE)
1174         {
1175                 if (bmcast)
1176                 {
1177                         /*  For AP mode, if DA == MCAST, then BSSID should be also MCAST */
1178                         if (!IS_MCAST(pattrib->bssid)){
1179                                         ret= _FAIL;
1180                                         goto exit;
1181                         }
1182                 }
1183                 else /*  not mc-frame */
1184                 {
1185                         /*  For AP mode, if DA is non-MCAST, then it must be BSSID, and bssid == BSSID */
1186                         if (memcmp(pattrib->bssid, pattrib->dst, ETH_ALEN)) {
1187                                 ret= _FAIL;
1188                                 goto exit;
1189                         }
1190
1191                         sta_addr = pattrib->src;
1192                 }
1193
1194         }
1195         else if(check_fwstate(pmlmepriv, WIFI_MP_STATE) == _TRUE)
1196         {
1197                 memcpy(pattrib->dst, GetAddr1Ptr(ptr), ETH_ALEN);
1198                 memcpy(pattrib->src, GetAddr2Ptr(ptr), ETH_ALEN);
1199                 memcpy(pattrib->bssid, GetAddr3Ptr(ptr), ETH_ALEN);
1200                 memcpy(pattrib->ra, pattrib->dst, ETH_ALEN);
1201                 memcpy(pattrib->ta, pattrib->src, ETH_ALEN);
1202
1203                 sta_addr = mybssid;
1204         }
1205         else
1206         {
1207                 ret  = _FAIL;
1208         }
1209
1210         if(bmcast)
1211                 *psta = rtw_get_bcmc_stainfo(adapter);
1212         else
1213                 *psta = rtw_get_stainfo(pstapriv, sta_addr); /*  get ap_info */
1214
1215 #ifdef CONFIG_TDLS
1216         if(ptdls_sta != NULL)
1217                 *psta = ptdls_sta;
1218 #endif /* CONFIG_TDLS */
1219
1220         if (*psta == NULL) {
1221                 RT_TRACE(_module_rtl871x_recv_c_,_drv_err_,("can't get psta under sta2sta_data_frame ; drop pkt\n"));
1222                 ret= _FAIL;
1223                 goto exit;
1224         }
1225
1226 exit:
1227 _func_exit_;
1228         return ret;
1229 }
1230
1231 int ap2sta_data_frame(
1232         _adapter *adapter,
1233         union recv_frame *precv_frame,
1234         struct sta_info**psta );
1235 int ap2sta_data_frame(
1236         _adapter *adapter,
1237         union recv_frame *precv_frame,
1238         struct sta_info**psta )
1239 {
1240         u8 *ptr = precv_frame->u.hdr.rx_data;
1241         struct rx_pkt_attrib *pattrib = & precv_frame->u.hdr.attrib;
1242         int ret = _SUCCESS;
1243         struct  sta_priv                *pstapriv = &adapter->stapriv;
1244         struct  mlme_priv       *pmlmepriv = &adapter->mlmepriv;
1245         u8 *mybssid  = get_bssid(pmlmepriv);
1246         u8 *myhwaddr = myid(&adapter->eeprompriv);
1247         int bmcast = IS_MCAST(pattrib->dst);
1248
1249 _func_enter_;
1250
1251         if ((check_fwstate(pmlmepriv, WIFI_STATION_STATE) == _TRUE)
1252                 && (check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE
1253                         || check_fwstate(pmlmepriv, _FW_UNDER_LINKING) == _TRUE )
1254                 )
1255         {
1256
1257                 /*  filter packets that SA is myself or multicast or broadcast */
1258                 if (!memcmp(myhwaddr, pattrib->src, ETH_ALEN)) {
1259                         RT_TRACE(_module_rtl871x_recv_c_,_drv_err_,(" SA==myself \n"));
1260                         #ifdef DBG_RX_DROP_FRAME
1261                         DBG_8723A("DBG_RX_DROP_FRAME %s SA="MAC_FMT", myhwaddr="MAC_FMT"\n",
1262                                 __FUNCTION__, MAC_ARG(pattrib->src), MAC_ARG(myhwaddr));
1263                         #endif
1264                         ret= _FAIL;
1265                         goto exit;
1266                 }
1267
1268                 /*  da should be for me */
1269                 if (memcmp(myhwaddr, pattrib->dst, ETH_ALEN) && (!bmcast))
1270                 {
1271                         RT_TRACE(_module_rtl871x_recv_c_,_drv_info_,
1272                                 (" ap2sta_data_frame:  compare DA fail; DA="MAC_FMT"\n", MAC_ARG(pattrib->dst)));
1273                         #ifdef DBG_RX_DROP_FRAME
1274                         DBG_8723A("DBG_RX_DROP_FRAME %s DA="MAC_FMT"\n", __func__, MAC_ARG(pattrib->dst));
1275                         #endif
1276                         ret= _FAIL;
1277                         goto exit;
1278                 }
1279
1280                 /*  check BSSID */
1281                 if (!memcmp(pattrib->bssid, "\x0\x0\x0\x0\x0\x0", ETH_ALEN) ||
1282                     !memcmp(mybssid, "\x0\x0\x0\x0\x0\x0", ETH_ALEN) ||
1283                     memcmp(pattrib->bssid, mybssid, ETH_ALEN)) {
1284                         RT_TRACE(_module_rtl871x_recv_c_,_drv_info_,
1285                                 (" ap2sta_data_frame:  compare BSSID fail ; BSSID="MAC_FMT"\n", MAC_ARG(pattrib->bssid)));
1286                         RT_TRACE(_module_rtl871x_recv_c_,_drv_info_,("mybssid="MAC_FMT"\n", MAC_ARG(mybssid)));
1287                         #ifdef DBG_RX_DROP_FRAME
1288                         DBG_8723A("DBG_RX_DROP_FRAME %s BSSID="MAC_FMT", mybssid="MAC_FMT"\n",
1289                                 __FUNCTION__, MAC_ARG(pattrib->bssid), MAC_ARG(mybssid));
1290                         DBG_8723A( "this adapter = %d, buddy adapter = %d\n", adapter->adapter_type, adapter->pbuddy_adapter->adapter_type );
1291                         #endif
1292
1293                         if(!bmcast)
1294                         {
1295                                 DBG_8723A("issue_deauth to the nonassociated ap=" MAC_FMT " for the reason(7)\n", MAC_ARG(pattrib->bssid));
1296                                 issue_deauth(adapter, pattrib->bssid, WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA);
1297                         }
1298
1299                         ret= _FAIL;
1300                         goto exit;
1301                 }
1302
1303                 if(bmcast)
1304                         *psta = rtw_get_bcmc_stainfo(adapter);
1305                 else
1306                         *psta = rtw_get_stainfo(pstapriv, pattrib->bssid); /*  get ap_info */
1307
1308                 if (*psta == NULL) {
1309                         RT_TRACE(_module_rtl871x_recv_c_,_drv_err_,("ap2sta: can't get psta under STATION_MODE ; drop pkt\n"));
1310                         #ifdef DBG_RX_DROP_FRAME
1311                         DBG_8723A("DBG_RX_DROP_FRAME %s can't get psta under STATION_MODE ; drop pkt\n", __FUNCTION__);
1312                         #endif
1313                         ret= _FAIL;
1314                         goto exit;
1315                 }
1316
1317                 /* if ((GetFrameSubType(ptr) & WIFI_QOS_DATA_TYPE) == WIFI_QOS_DATA_TYPE) { */
1318                 /*  */
1319
1320                 if (GetFrameSubType(ptr) & BIT(6)) {
1321                         /* No data, will not indicate to upper layer, temporily count it here */
1322                         count_rx_stats(adapter, precv_frame, *psta);
1323                         ret = RTW_RX_HANDLED;
1324                         goto exit;
1325                 }
1326
1327         }
1328         else if ((check_fwstate(pmlmepriv, WIFI_MP_STATE) == _TRUE) &&
1329                      (check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE) )
1330         {
1331                 memcpy(pattrib->dst, GetAddr1Ptr(ptr), ETH_ALEN);
1332                 memcpy(pattrib->src, GetAddr2Ptr(ptr), ETH_ALEN);
1333                 memcpy(pattrib->bssid, GetAddr3Ptr(ptr), ETH_ALEN);
1334                 memcpy(pattrib->ra, pattrib->dst, ETH_ALEN);
1335                 memcpy(pattrib->ta, pattrib->src, ETH_ALEN);
1336
1337                 /*  */
1338                 memcpy(pattrib->bssid,  mybssid, ETH_ALEN);
1339
1340                 *psta = rtw_get_stainfo(pstapriv, pattrib->bssid); /*  get sta_info */
1341                 if (*psta == NULL) {
1342                         RT_TRACE(_module_rtl871x_recv_c_,_drv_err_,("can't get psta under MP_MODE ; drop pkt\n"));
1343                         #ifdef DBG_RX_DROP_FRAME
1344                         DBG_8723A("DBG_RX_DROP_FRAME %s can't get psta under WIFI_MP_STATE ; drop pkt\n", __FUNCTION__);
1345                         #endif
1346                         ret= _FAIL;
1347                         goto exit;
1348                 }
1349
1350         }
1351         else if (check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE)
1352         {
1353                 /* Special case */
1354                 ret = RTW_RX_HANDLED;
1355                 goto exit;
1356         }
1357         else
1358         {
1359                 if (!memcmp(myhwaddr, pattrib->dst, ETH_ALEN) && (!bmcast))
1360                 {
1361                         *psta = rtw_get_stainfo(pstapriv, pattrib->bssid); /*  get sta_info */
1362                         if (*psta == NULL)
1363                         {
1364                                 DBG_8723A("issue_deauth to the ap=" MAC_FMT " for the reason(7)\n", MAC_ARG(pattrib->bssid));
1365
1366                                 issue_deauth(adapter, pattrib->bssid, WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA);
1367                         }
1368                 }
1369
1370                 ret = _FAIL;
1371                 #ifdef DBG_RX_DROP_FRAME
1372                 DBG_8723A("DBG_RX_DROP_FRAME %s fw_state:0x%x\n", __FUNCTION__, get_fwstate(pmlmepriv));
1373                 #endif
1374         }
1375
1376 exit:
1377
1378 _func_exit_;
1379
1380         return ret;
1381 }
1382
1383 int sta2ap_data_frame(
1384         _adapter *adapter,
1385         union recv_frame *precv_frame,
1386         struct sta_info**psta );
1387 int sta2ap_data_frame(
1388         _adapter *adapter,
1389         union recv_frame *precv_frame,
1390         struct sta_info**psta )
1391 {
1392         u8 *ptr = precv_frame->u.hdr.rx_data;
1393         struct rx_pkt_attrib *pattrib = & precv_frame->u.hdr.attrib;
1394         struct  sta_priv                *pstapriv = &adapter->stapriv;
1395         struct  mlme_priv       *pmlmepriv = &adapter->mlmepriv;
1396         unsigned char *mybssid  = get_bssid(pmlmepriv);
1397         int ret=_SUCCESS;
1398
1399 _func_enter_;
1400
1401         if (check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE)
1402         {
1403                 /* For AP mode, RA=BSSID, TX=STA(SRC_ADDR), A3=DST_ADDR */
1404                 if(memcmp(pattrib->bssid, mybssid, ETH_ALEN))
1405                 {
1406                         ret= _FAIL;
1407                         goto exit;
1408                 }
1409
1410                 *psta = rtw_get_stainfo(pstapriv, pattrib->src);
1411                 if (*psta == NULL)
1412                 {
1413                         RT_TRACE(_module_rtl871x_recv_c_,_drv_err_,("can't get psta under AP_MODE; drop pkt\n"));
1414                         DBG_8723A("issue_deauth to sta=" MAC_FMT " for the reason(7)\n", MAC_ARG(pattrib->src));
1415
1416                         issue_deauth(adapter, pattrib->src, WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA);
1417
1418                         ret = RTW_RX_HANDLED;
1419                         goto exit;
1420                 }
1421
1422                 process_pwrbit_data(adapter, precv_frame);
1423
1424                 if ((GetFrameSubType(ptr) & WIFI_QOS_DATA_TYPE) == WIFI_QOS_DATA_TYPE) {
1425                         process_wmmps_data(adapter, precv_frame);
1426                 }
1427
1428                 if (GetFrameSubType(ptr) & BIT(6)) {
1429                         /* No data, will not indicate to upper layer, temporily count it here */
1430                         count_rx_stats(adapter, precv_frame, *psta);
1431                         ret = RTW_RX_HANDLED;
1432                         goto exit;
1433                 }
1434         }
1435         else {
1436                 u8 *myhwaddr = myid(&adapter->eeprompriv);
1437                 if (memcmp(pattrib->ra, myhwaddr, ETH_ALEN)) {
1438                         ret = RTW_RX_HANDLED;
1439                         goto exit;
1440                 }
1441                 DBG_8723A("issue_deauth to sta=" MAC_FMT " for the reason(7)\n", MAC_ARG(pattrib->src));
1442                 issue_deauth(adapter, pattrib->src, WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA);
1443                 ret = RTW_RX_HANDLED;
1444                 goto exit;
1445         }
1446
1447 exit:
1448
1449 _func_exit_;
1450
1451         return ret;
1452 }
1453
1454 int validate_recv_ctrl_frame(_adapter *padapter, union recv_frame *precv_frame);
1455 int validate_recv_ctrl_frame(_adapter *padapter, union recv_frame *precv_frame)
1456 {
1457 #ifdef CONFIG_AP_MODE
1458         struct rx_pkt_attrib *pattrib = &precv_frame->u.hdr.attrib;
1459         struct sta_priv *pstapriv = &padapter->stapriv;
1460         u8 *pframe = precv_frame->u.hdr.rx_data;
1461         /* uint len = precv_frame->u.hdr.len; */
1462
1463         /* DBG_8723A("+validate_recv_ctrl_frame\n"); */
1464
1465         if (GetFrameType(pframe) != WIFI_CTRL_TYPE)
1466         {
1467                 return _FAIL;
1468         }
1469
1470         /* receive the frames that ra(a1) is my address */
1471         if (memcmp(GetAddr1Ptr(pframe), myid(&padapter->eeprompriv), ETH_ALEN))
1472         {
1473                 return _FAIL;
1474         }
1475
1476         /* only handle ps-poll */
1477         if(GetFrameSubType(pframe) == WIFI_PSPOLL)
1478         {
1479                 u16 aid;
1480                 u8 wmmps_ac=0;
1481                 struct sta_info *psta=NULL;
1482
1483                 aid = GetAid(pframe);
1484                 psta = rtw_get_stainfo(pstapriv, GetAddr2Ptr(pframe));
1485
1486                 if((psta==NULL) || (psta->aid!=aid))
1487                 {
1488                         return _FAIL;
1489                 }
1490
1491                 /* for rx pkt statistics */
1492                 psta->sta_stats.rx_ctrl_pkts++;
1493
1494                 switch(pattrib->priority)
1495                 {
1496                         case 1:
1497                         case 2:
1498                                 wmmps_ac = psta->uapsd_bk&BIT(0);
1499                                 break;
1500                         case 4:
1501                         case 5:
1502                                 wmmps_ac = psta->uapsd_vi&BIT(0);
1503                                 break;
1504                         case 6:
1505                         case 7:
1506                                 wmmps_ac = psta->uapsd_vo&BIT(0);
1507                                 break;
1508                         case 0:
1509                         case 3:
1510                         default:
1511                                 wmmps_ac = psta->uapsd_be&BIT(0);
1512                                 break;
1513                 }
1514
1515                 if(wmmps_ac)
1516                         return _FAIL;
1517
1518                 if(psta->state & WIFI_STA_ALIVE_CHK_STATE)
1519                 {
1520                         DBG_8723A("%s alive check-rx ps-poll\n", __func__);
1521                         psta->expire_to = pstapriv->expire_to;
1522                         psta->state ^= WIFI_STA_ALIVE_CHK_STATE;
1523                 }
1524
1525                 if((psta->state&WIFI_SLEEP_STATE) && (pstapriv->sta_dz_bitmap&BIT(psta->aid)))
1526                 {
1527                         _irqL irqL;
1528                         _list   *xmitframe_plist, *xmitframe_phead;
1529                         struct xmit_frame *pxmitframe=NULL;
1530                         struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
1531
1532                         /* spin_lock_bh(&psta->sleep_q.lock); */
1533                         spin_lock_bh(&pxmitpriv->lock);
1534
1535                         xmitframe_phead = get_list_head(&psta->sleep_q);
1536                         xmitframe_plist = get_next(xmitframe_phead);
1537
1538                         if ((rtw_end_of_queue_search(xmitframe_phead, xmitframe_plist)) == _FALSE)
1539                         {
1540                                 pxmitframe = LIST_CONTAINOR(xmitframe_plist, struct xmit_frame, list);
1541
1542                                 xmitframe_plist = get_next(xmitframe_plist);
1543
1544                                 rtw_list_delete(&pxmitframe->list);
1545
1546                                 psta->sleepq_len--;
1547
1548                                 if(psta->sleepq_len>0)
1549                                         pxmitframe->attrib.mdata = 1;
1550                                 else
1551                                         pxmitframe->attrib.mdata = 0;
1552
1553                                 pxmitframe->attrib.triggered = 1;
1554
1555                                 /* DBG_8723A("handling ps-poll, q_len=%d, tim=%x\n", psta->sleepq_len, pstapriv->tim_bitmap); */
1556
1557                                 rtw_hal_xmitframe_enqueue(padapter, pxmitframe);
1558
1559                                 if(psta->sleepq_len==0)
1560                                 {
1561                                         pstapriv->tim_bitmap &= ~BIT(psta->aid);
1562
1563                                         /* DBG_8723A("after handling ps-poll, tim=%x\n", pstapriv->tim_bitmap); */
1564
1565                                         /* upate BCN for TIM IE */
1566                                         /* update_BCNTIM(padapter); */
1567                                         update_beacon(padapter, _TIM_IE_, NULL, _FALSE);
1568                                 }
1569
1570                                 /* spin_unlock_bh(&psta->sleep_q.lock); */
1571                                 spin_unlock_bh(&pxmitpriv->lock);
1572
1573                         }
1574                         else
1575                         {
1576                                 /* spin_unlock_bh(&psta->sleep_q.lock); */
1577                                 spin_unlock_bh(&pxmitpriv->lock);
1578
1579                                 /* DBG_8723A("no buffered packets to xmit\n"); */
1580                                 if(pstapriv->tim_bitmap&BIT(psta->aid))
1581                                 {
1582                                         if(psta->sleepq_len==0)
1583                                         {
1584                                                 DBG_8723A("no buffered packets to xmit\n");
1585
1586                                                 /* issue nulldata with More data bit = 0 to indicate we have no buffered packets */
1587                                                 issue_nulldata(padapter, psta->hwaddr, 0, 0, 0);
1588                                         }
1589                                         else
1590                                         {
1591                                                 DBG_8723A("error!psta->sleepq_len=%d\n", psta->sleepq_len);
1592                                                 psta->sleepq_len=0;
1593                                         }
1594
1595                                         pstapriv->tim_bitmap &= ~BIT(psta->aid);
1596
1597                                         /* upate BCN for TIM IE */
1598                                         /* update_BCNTIM(padapter); */
1599                                         update_beacon(padapter, _TIM_IE_, NULL, _FALSE);
1600                                 }
1601
1602                         }
1603
1604                 }
1605
1606         }
1607
1608 #endif
1609
1610         return _FAIL;
1611 }
1612
1613 union recv_frame* recvframe_chk_defrag(PADAPTER padapter, union recv_frame *precv_frame);
1614 int validate_recv_mgnt_frame(PADAPTER padapter, union recv_frame *precv_frame);
1615 int validate_recv_mgnt_frame(PADAPTER padapter, union recv_frame *precv_frame)
1616 {
1617         /* struct mlme_priv *pmlmepriv = &adapter->mlmepriv; */
1618
1619         RT_TRACE(_module_rtl871x_recv_c_, _drv_info_, ("+validate_recv_mgnt_frame\n"));
1620
1621         precv_frame = recvframe_chk_defrag(padapter, precv_frame);
1622         if (precv_frame == NULL) {
1623                 RT_TRACE(_module_rtl871x_recv_c_, _drv_notice_,("%s: fragment packet\n",__FUNCTION__));
1624                 return _SUCCESS;
1625         }
1626
1627         {
1628                 /* for rx pkt statistics */
1629                 struct sta_info *psta = rtw_get_stainfo(&padapter->stapriv, GetAddr2Ptr(precv_frame->u.hdr.rx_data));
1630                 if (psta) {
1631                         psta->sta_stats.rx_mgnt_pkts++;
1632                         if (GetFrameSubType(precv_frame->u.hdr.rx_data) == WIFI_BEACON)
1633                                 psta->sta_stats.rx_beacon_pkts++;
1634                         else if (GetFrameSubType(precv_frame->u.hdr.rx_data) == WIFI_PROBEREQ)
1635                                 psta->sta_stats.rx_probereq_pkts++;
1636                         else if (GetFrameSubType(precv_frame->u.hdr.rx_data) == WIFI_PROBERSP) {
1637                                 if (!memcmp(padapter->eeprompriv.mac_addr, GetAddr1Ptr(precv_frame->u.hdr.rx_data), ETH_ALEN))
1638                                         psta->sta_stats.rx_probersp_pkts++;
1639                                 else if (is_broadcast_mac_addr(GetAddr1Ptr(precv_frame->u.hdr.rx_data))
1640                                         || is_multicast_mac_addr(GetAddr1Ptr(precv_frame->u.hdr.rx_data)))
1641                                         psta->sta_stats.rx_probersp_bm_pkts++;
1642                                 else
1643                                         psta->sta_stats.rx_probersp_uo_pkts++;
1644                         }
1645                 }
1646         }
1647
1648 #ifdef CONFIG_INTEL_PROXIM
1649         if(padapter->proximity.proxim_on==_TRUE)
1650         {
1651                 struct rx_pkt_attrib * pattrib=&precv_frame->u.hdr.attrib;
1652                  struct recv_stat* prxstat=( struct recv_stat * )  precv_frame->u.hdr.rx_head ;
1653                  u8 * pda,*psa,*pbssid,*ptr;
1654                  ptr=precv_frame->u.hdr.rx_data;
1655                 pda = get_da(ptr);
1656                 psa = get_sa(ptr);
1657                 pbssid = get_hdr_bssid(ptr);
1658
1659                 memcpy(pattrib->dst, pda, ETH_ALEN);
1660                 memcpy(pattrib->src, psa, ETH_ALEN);
1661
1662                 memcpy(pattrib->bssid, pbssid, ETH_ALEN);
1663
1664         switch(pattrib->to_fr_ds)
1665         {
1666                 case 0:
1667                         memcpy(pattrib->ra, pda, ETH_ALEN);
1668                         memcpy(pattrib->ta, psa, ETH_ALEN);
1669                         break;
1670
1671                 case 1:
1672                         memcpy(pattrib->ra, pda, ETH_ALEN);
1673                         memcpy(pattrib->ta, pbssid, ETH_ALEN);
1674                         break;
1675
1676                 case 2:
1677                         memcpy(pattrib->ra, pbssid, ETH_ALEN);
1678                         memcpy(pattrib->ta, psa, ETH_ALEN);
1679                         break;
1680
1681                 case 3:
1682                         memcpy(pattrib->ra, GetAddr1Ptr(ptr), ETH_ALEN);
1683                         memcpy(pattrib->ta, GetAddr2Ptr(ptr), ETH_ALEN);
1684                         RT_TRACE(_module_rtl871x_recv_c_,_drv_err_,(" case 3\n"));
1685                         break;
1686
1687                 default:
1688                         break;
1689
1690                 }
1691                         pattrib->priority=0;
1692                         pattrib->hdrlen = pattrib->to_fr_ds==3 ? 30 : 24;
1693
1694                  padapter->proximity.proxim_rx(padapter,precv_frame);
1695         }
1696 #endif
1697         mgt_dispatcher(padapter, precv_frame);
1698
1699         return _SUCCESS;
1700 }
1701
1702 int validate_recv_data_frame(_adapter *adapter, union recv_frame *precv_frame);
1703 int validate_recv_data_frame(_adapter *adapter, union recv_frame *precv_frame)
1704 {
1705         u8 bretry;
1706         u8 *psa, *pda, *pbssid;
1707         struct sta_info *psta = NULL;
1708         u8 *ptr = precv_frame->u.hdr.rx_data;
1709         struct rx_pkt_attrib    *pattrib = & precv_frame->u.hdr.attrib;
1710         struct sta_priv         *pstapriv = &adapter->stapriv;
1711         struct security_priv    *psecuritypriv = &adapter->securitypriv;
1712         int ret = _SUCCESS;
1713 #ifdef CONFIG_TDLS
1714         struct tdls_info *ptdlsinfo = &adapter->tdlsinfo;
1715 #endif /* CONFIG_TDLS */
1716
1717 _func_enter_;
1718
1719         bretry = GetRetry(ptr);
1720         pda = get_da(ptr);
1721         psa = get_sa(ptr);
1722         pbssid = get_hdr_bssid(ptr);
1723
1724         if(pbssid == NULL){
1725                 #ifdef DBG_RX_DROP_FRAME
1726                 DBG_8723A("DBG_RX_DROP_FRAME %s pbssid == NULL\n", __func__);
1727                 #endif
1728                 ret= _FAIL;
1729                 goto exit;
1730         }
1731
1732         memcpy(pattrib->dst, pda, ETH_ALEN);
1733         memcpy(pattrib->src, psa, ETH_ALEN);
1734
1735         memcpy(pattrib->bssid, pbssid, ETH_ALEN);
1736
1737         switch(pattrib->to_fr_ds)
1738         {
1739                 case 0:
1740                         memcpy(pattrib->ra, pda, ETH_ALEN);
1741                         memcpy(pattrib->ta, psa, ETH_ALEN);
1742                         ret = sta2sta_data_frame(adapter, precv_frame, &psta);
1743                         break;
1744
1745                 case 1:
1746                         memcpy(pattrib->ra, pda, ETH_ALEN);
1747                         memcpy(pattrib->ta, pbssid, ETH_ALEN);
1748                         ret = ap2sta_data_frame(adapter, precv_frame, &psta);
1749                         break;
1750
1751                 case 2:
1752                         memcpy(pattrib->ra, pbssid, ETH_ALEN);
1753                         memcpy(pattrib->ta, psa, ETH_ALEN);
1754                         ret = sta2ap_data_frame(adapter, precv_frame, &psta);
1755                         break;
1756
1757                 case 3:
1758                         memcpy(pattrib->ra, GetAddr1Ptr(ptr), ETH_ALEN);
1759                         memcpy(pattrib->ta, GetAddr2Ptr(ptr), ETH_ALEN);
1760                         ret =_FAIL;
1761                         RT_TRACE(_module_rtl871x_recv_c_,_drv_err_,(" case 3\n"));
1762                         break;
1763
1764                 default:
1765                         ret =_FAIL;
1766                         break;
1767
1768         }
1769
1770         if(ret ==_FAIL){
1771                 #ifdef DBG_RX_DROP_FRAME
1772                 DBG_8723A("DBG_RX_DROP_FRAME %s case:%d, res:%d\n", __FUNCTION__, pattrib->to_fr_ds, ret);
1773                 #endif
1774                 goto exit;
1775         } else if (ret == RTW_RX_HANDLED) {
1776                 goto exit;
1777         }
1778
1779         if(psta==NULL){
1780                 RT_TRACE(_module_rtl871x_recv_c_,_drv_err_,(" after to_fr_ds_chk; psta==NULL \n"));
1781                 #ifdef DBG_RX_DROP_FRAME
1782                 DBG_8723A("DBG_RX_DROP_FRAME %s psta == NULL\n", __func__);
1783                 #endif
1784                 ret= _FAIL;
1785                 goto exit;
1786         }
1787
1788         /* psta->rssi = prxcmd->rssi; */
1789         /* psta->signal_quality= prxcmd->sq; */
1790         precv_frame->u.hdr.psta = psta;
1791
1792         pattrib->amsdu=0;
1793         pattrib->ack_policy = 0;
1794         /* parsing QC field */
1795         if(pattrib->qos == 1)
1796         {
1797                 pattrib->priority = GetPriority((ptr + 24));
1798                 pattrib->ack_policy = GetAckpolicy((ptr + 24));
1799                 pattrib->amsdu = GetAMsdu((ptr + 24));
1800                 pattrib->hdrlen = pattrib->to_fr_ds==3 ? 32 : 26;
1801
1802                 if(pattrib->priority!=0 && pattrib->priority!=3)
1803                 {
1804                         adapter->recvpriv.bIsAnyNonBEPkts = _TRUE;
1805                 }
1806         }
1807         else
1808         {
1809                 pattrib->priority=0;
1810                 pattrib->hdrlen = pattrib->to_fr_ds==3 ? 30 : 24;
1811         }
1812
1813         if(pattrib->order)/* HT-CTRL 11n */
1814         {
1815                 pattrib->hdrlen += 4;
1816         }
1817
1818         precv_frame->u.hdr.preorder_ctrl = &psta->recvreorder_ctrl[pattrib->priority];
1819
1820         /*  decache, drop duplicate recv packets */
1821         if(recv_decache(precv_frame, bretry, &psta->sta_recvpriv.rxcache) == _FAIL)
1822         {
1823                 RT_TRACE(_module_rtl871x_recv_c_,_drv_err_,("decache : drop pkt\n"));
1824                 #ifdef DBG_RX_DROP_FRAME
1825                 DBG_8723A("DBG_RX_DROP_FRAME %s recv_decache return _FAIL\n", __func__);
1826                 #endif
1827                 ret= _FAIL;
1828                 goto exit;
1829         }
1830
1831         if(pattrib->privacy){
1832
1833                 RT_TRACE(_module_rtl871x_recv_c_,_drv_info_,("validate_recv_data_frame:pattrib->privacy=%x\n", pattrib->privacy));
1834                 RT_TRACE(_module_rtl871x_recv_c_,_drv_info_,("\n ^^^^^^^^^^^IS_MCAST(pattrib->ra(0x%02x))=%d^^^^^^^^^^^^^^^6\n", pattrib->ra[0],IS_MCAST(pattrib->ra)));
1835
1836 #ifdef CONFIG_TDLS
1837                 if((psta->tdls_sta_state & TDLS_LINKED_STATE) && (psta->dot118021XPrivacy==_AES_))
1838                 {
1839                         pattrib->encrypt=psta->dot118021XPrivacy;
1840                 }
1841                 else
1842 #endif /* CONFIG_TDLS */
1843                 GET_ENCRY_ALGO(psecuritypriv, psta, pattrib->encrypt, IS_MCAST(pattrib->ra));
1844
1845                 RT_TRACE(_module_rtl871x_recv_c_,_drv_info_,("\n pattrib->encrypt=%d\n",pattrib->encrypt));
1846
1847                 SET_ICE_IV_LEN(pattrib->iv_len, pattrib->icv_len, pattrib->encrypt);
1848         }
1849         else
1850         {
1851                 pattrib->encrypt = 0;
1852                 pattrib->iv_len = pattrib->icv_len = 0;
1853         }
1854
1855 exit:
1856
1857 _func_exit_;
1858
1859         return ret;
1860 }
1861
1862 int validate_recv_frame(_adapter *adapter, union recv_frame *precv_frame);
1863 int validate_recv_frame(_adapter *adapter, union recv_frame *precv_frame)
1864 {
1865         /* shall check frame subtype, to / from ds, da, bssid */
1866
1867         /* then call check if rx seq/frag. duplicated. */
1868
1869         u8 type;
1870         u8 subtype;
1871         int retval = _SUCCESS;
1872
1873         struct rx_pkt_attrib *pattrib = & precv_frame->u.hdr.attrib;
1874
1875         u8 *ptr = precv_frame->u.hdr.rx_data;
1876         u8  ver =(unsigned char) (*ptr)&0x3 ;
1877 #ifdef CONFIG_FIND_BEST_CHANNEL
1878         struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv;
1879 #endif
1880
1881 #ifdef CONFIG_TDLS
1882         struct tdls_info *ptdlsinfo = &adapter->tdlsinfo;
1883 #endif /* CONFIG_TDLS */
1884 #ifdef CONFIG_WAPI_SUPPORT
1885         PRT_WAPI_T      pWapiInfo = &adapter->wapiInfo;
1886         struct recv_frame_hdr *phdr = &precv_frame->u.hdr;
1887         u8 wai_pkt = 0;
1888         u16 sc;
1889         u8      external_len = 0;
1890 #endif
1891
1892 _func_enter_;
1893
1894 #ifdef CONFIG_FIND_BEST_CHANNEL
1895         if (pmlmeext->sitesurvey_res.state == SCAN_PROCESS) {
1896                 int ch_set_idx = rtw_ch_set_search_ch(pmlmeext->channel_set, rtw_get_oper_ch(adapter));
1897                 if (ch_set_idx >= 0)
1898                         pmlmeext->channel_set[ch_set_idx].rx_count++;
1899         }
1900 #endif
1901
1902 #ifdef CONFIG_TDLS
1903         if(ptdlsinfo->ch_sensing==1 && ptdlsinfo->cur_channel !=0){
1904                 ptdlsinfo->collect_pkt_num[ptdlsinfo->cur_channel-1]++;
1905         }
1906 #endif /* CONFIG_TDLS */
1907
1908         /* add version chk */
1909         if(ver!=0){
1910                 RT_TRACE(_module_rtl871x_recv_c_,_drv_err_,("validate_recv_data_frame fail! (ver!=0)\n"));
1911                 retval= _FAIL;
1912                 goto exit;
1913         }
1914
1915         type =  GetFrameType(ptr);
1916         subtype = GetFrameSubType(ptr); /* bit(7)~bit(2) */
1917
1918         pattrib->to_fr_ds = get_tofr_ds(ptr);
1919
1920         pattrib->frag_num = GetFragNum(ptr);
1921         pattrib->seq_num = GetSequence(ptr);
1922
1923         pattrib->pw_save = GetPwrMgt(ptr);
1924         pattrib->mfrag = GetMFrag(ptr);
1925         pattrib->mdata = GetMData(ptr);
1926         pattrib->privacy = GetPrivacy(ptr);
1927         pattrib->order = GetOrder(ptr);
1928 #ifdef CONFIG_WAPI_SUPPORT
1929         sc = (pattrib->seq_num<<4) | pattrib->frag_num;
1930 #endif
1931
1932 #if 1 /* Dump rx packets */
1933 {
1934         u8 bDumpRxPkt;
1935         rtw_hal_get_def_var(adapter, HAL_DEF_DBG_DUMP_RXPKT, &(bDumpRxPkt));
1936         if(bDumpRxPkt ==1){/* dump all rx packets */
1937                 int i;
1938                 DBG_8723A("############################# \n");
1939
1940                 for(i=0; i<64;i=i+8)
1941                         DBG_8723A("%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:\n", *(ptr+i),
1942                         *(ptr+i+1), *(ptr+i+2) ,*(ptr+i+3) ,*(ptr+i+4),*(ptr+i+5), *(ptr+i+6), *(ptr+i+7));
1943                 DBG_8723A("############################# \n");
1944         }
1945         else if(bDumpRxPkt ==2){
1946                 if(type== WIFI_MGT_TYPE){
1947                         int i;
1948                         DBG_8723A("############################# \n");
1949
1950                         for(i=0; i<64;i=i+8)
1951                                 DBG_8723A("%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:\n", *(ptr+i),
1952                                 *(ptr+i+1), *(ptr+i+2) ,*(ptr+i+3) ,*(ptr+i+4),*(ptr+i+5), *(ptr+i+6), *(ptr+i+7));
1953                         DBG_8723A("############################# \n");
1954                 }
1955         }
1956         else if(bDumpRxPkt ==3){
1957                 if(type== WIFI_DATA_TYPE){
1958                         int i;
1959                         DBG_8723A("############################# \n");
1960
1961                         for(i=0; i<64;i=i+8)
1962                                 DBG_8723A("%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:\n", *(ptr+i),
1963                                 *(ptr+i+1), *(ptr+i+2) ,*(ptr+i+3) ,*(ptr+i+4),*(ptr+i+5), *(ptr+i+6), *(ptr+i+7));
1964                         DBG_8723A("############################# \n");
1965                 }
1966         }
1967 }
1968 #endif
1969         switch (type)
1970         {
1971                 case WIFI_MGT_TYPE: /* mgnt */
1972                         retval = validate_recv_mgnt_frame(adapter, precv_frame);
1973                         if (retval == _FAIL)
1974                         {
1975                                 RT_TRACE(_module_rtl871x_recv_c_,_drv_err_,("validate_recv_mgnt_frame fail\n"));
1976                         }
1977                         retval = _FAIL; /*  only data frame return _SUCCESS */
1978                         break;
1979                 case WIFI_CTRL_TYPE: /* ctrl */
1980                         retval = validate_recv_ctrl_frame(adapter, precv_frame);
1981                         if (retval == _FAIL)
1982                         {
1983                                 RT_TRACE(_module_rtl871x_recv_c_,_drv_err_,("validate_recv_ctrl_frame fail\n"));
1984                         }
1985                         retval = _FAIL; /*  only data frame return _SUCCESS */
1986                         break;
1987                 case WIFI_DATA_TYPE: /* data */
1988 #ifdef CONFIG_WAPI_SUPPORT
1989                         if(pattrib->qos)
1990                                 external_len = 2;
1991                         else
1992                                 external_len= 0;
1993
1994                         wai_pkt = rtw_wapi_is_wai_packet(adapter,ptr);
1995
1996                         phdr->bIsWaiPacket = wai_pkt;
1997
1998                         if(wai_pkt !=0){
1999                                 if(sc != adapter->wapiInfo.wapiSeqnumAndFragNum)
2000                                 {
2001                                         adapter->wapiInfo.wapiSeqnumAndFragNum = sc;
2002                                 }
2003                                 else
2004                                 {
2005                                         retval = _FAIL;
2006                                         break;
2007                                 }
2008                         }
2009                         else{
2010
2011                                         if(rtw_wapi_drop_for_key_absent(adapter,GetAddr2Ptr(ptr))){
2012                                                 retval=_FAIL;
2013                                                 WAPI_TRACE(WAPI_RX,"drop for key absent for rx \n");
2014                                                 break;
2015                                         }
2016                         }
2017
2018 #endif
2019
2020                         rtw_led_control(adapter, LED_CTL_RX);
2021                         pattrib->qos = (subtype & BIT(7))? 1:0;
2022                         retval = validate_recv_data_frame(adapter, precv_frame);
2023                         if (retval == _FAIL)
2024                         {
2025                                 struct recv_priv *precvpriv = &adapter->recvpriv;
2026                                 /* RT_TRACE(_module_rtl871x_recv_c_,_drv_err_,("validate_recv_data_frame fail\n")); */
2027                                 precvpriv->rx_drop++;
2028                         }
2029                         break;
2030                 default:
2031                         RT_TRACE(_module_rtl871x_recv_c_,_drv_err_,("validate_recv_data_frame fail! type=0x%x\n", type));
2032                         #ifdef DBG_RX_DROP_FRAME
2033                         DBG_8723A("DBG_RX_DROP_FRAME validate_recv_data_frame fail! type=0x%x\n", type);
2034                         #endif
2035                         retval = _FAIL;
2036                         break;
2037         }
2038
2039 exit:
2040
2041 _func_exit_;
2042
2043         return retval;
2044 }
2045
2046 /* remove the wlanhdr and add the eth_hdr */
2047
2048 int wlanhdr_to_ethhdr ( union recv_frame *precvframe)
2049 {
2050         int     rmv_len;
2051         u16     eth_type, len;
2052         u8      bsnaphdr;
2053         u8      *psnap_type;
2054         struct ieee80211_snap_hdr       *psnap;
2055
2056         int ret=_SUCCESS;
2057         _adapter                        *adapter =precvframe->u.hdr.adapter;
2058         struct mlme_priv        *pmlmepriv = &adapter->mlmepriv;
2059
2060         u8      *ptr = get_recvframe_data(precvframe) ; /*  point to frame_ctrl field */
2061         struct rx_pkt_attrib *pattrib = & precvframe->u.hdr.attrib;
2062
2063 _func_enter_;
2064
2065         if(pattrib->encrypt){
2066                 recvframe_pull_tail(precvframe, pattrib->icv_len);
2067         }
2068
2069         psnap=(struct ieee80211_snap_hdr        *)(ptr+pattrib->hdrlen + pattrib->iv_len);
2070         psnap_type=ptr+pattrib->hdrlen + pattrib->iv_len+SNAP_SIZE;
2071         /* convert hdr + possible LLC headers into Ethernet header */
2072         /* eth_type = (psnap_type[0] << 8) | psnap_type[1]; */
2073         if ((!memcmp(psnap, rtw_rfc1042_header, SNAP_SIZE) &&
2074              memcmp(psnap_type, SNAP_ETH_TYPE_IPX, 2) &&
2075              memcmp(psnap_type, SNAP_ETH_TYPE_APPLETALK_AARP, 2)) ||
2076              /* eth_type != ETH_P_AARP && eth_type != ETH_P_IPX) || */
2077             !memcmp(psnap, rtw_bridge_tunnel_header, SNAP_SIZE)) {
2078                 /* remove RFC1042 or Bridge-Tunnel encapsulation and replace EtherType */
2079                 bsnaphdr = _TRUE;
2080         }
2081         else {
2082                 /* Leave Ethernet header part of hdr and full payload */
2083                 bsnaphdr = _FALSE;
2084         }
2085
2086         rmv_len = pattrib->hdrlen + pattrib->iv_len +(bsnaphdr?SNAP_SIZE:0);
2087         len = precvframe->u.hdr.len - rmv_len;
2088
2089         RT_TRACE(_module_rtl871x_recv_c_,_drv_info_,("\n===pattrib->hdrlen: %x,  pattrib->iv_len:%x ===\n\n", pattrib->hdrlen,  pattrib->iv_len));
2090
2091         memcpy(&eth_type, ptr+rmv_len, 2);
2092         eth_type= ntohs((unsigned short )eth_type); /* pattrib->ether_type */
2093         pattrib->eth_type = eth_type;
2094
2095         if ((check_fwstate(pmlmepriv, WIFI_MP_STATE) == _TRUE))
2096         {
2097                 ptr += rmv_len ;
2098                 *ptr = 0x87;
2099                 *(ptr+1) = 0x12;
2100
2101                 eth_type = 0x8712;
2102                 /*  append rx status for mp test packets */
2103                 ptr = recvframe_pull(precvframe, (rmv_len-sizeof(struct ethhdr)+2)-24);
2104                 memcpy(ptr, get_rxmem(precvframe), 24);
2105                 ptr+=24;
2106         }
2107         else {
2108                 ptr = recvframe_pull(precvframe, (rmv_len-sizeof(struct ethhdr)+ (bsnaphdr?2:0)));
2109         }
2110
2111         memcpy(ptr, pattrib->dst, ETH_ALEN);
2112         memcpy(ptr+ETH_ALEN, pattrib->src, ETH_ALEN);
2113
2114         if(!bsnaphdr) {
2115                 len = htons(len);
2116                 memcpy(ptr+12, &len, 2);
2117         }
2118
2119 _func_exit_;
2120         return ret;
2121 }
2122
2123 #if defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI)
2124 static void recvframe_expand_pkt(
2125         PADAPTER padapter,
2126         union recv_frame *prframe)
2127 {
2128         struct recv_frame_hdr *pfhdr;
2129         _pkt *ppkt;
2130         u8 shift_sz;
2131         u32 alloc_sz;
2132
2133         pfhdr = &prframe->u.hdr;
2134
2135         /*      6 is for IP header 8 bytes alignment in QoS packet case. */
2136         if (pfhdr->attrib.qos)
2137                 shift_sz = 6;
2138         else
2139                 shift_sz = 0;
2140
2141         /*  for first fragment packet, need to allocate */
2142         /*  (1536 + RXDESC_SIZE + drvinfo_sz) to reassemble packet */
2143         /*      8 is for skb->data 8 bytes alignment. */
2144 /*      alloc_sz = _RND(1536 + RXDESC_SIZE + pfhdr->attrib.drvinfosize + shift_sz + 8, 128); */
2145         alloc_sz = 1664; /*  round (1536 + 24 + 32 + shift_sz + 8) to 128 bytes alignment */
2146
2147         /* 3 1. alloc new skb */
2148         /*  prepare extra space for 4 bytes alignment */
2149 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,18)) /*  http:www.mail-archive.com/netdev@vger.kernel.org/msg17214.html */
2150         ppkt = dev_alloc_skb(alloc_sz);
2151         if (ppkt) ppkt->dev = padapter->pnetdev;
2152 #else
2153         ppkt = netdev_alloc_skb(padapter->pnetdev, alloc_sz);
2154 #endif
2155         if (!ppkt) return; /*  no way to expand */
2156
2157         /* 3 2. Prepare new skb to replace & release old skb */
2158         /*  force ppkt->data at 8-byte alignment address */
2159         skb_reserve(ppkt, 8 - ((unsigned long)ppkt->data & 7));
2160         /*  force ip_hdr at 8-byte alignment address according to shift_sz */
2161         skb_reserve(ppkt, shift_sz);
2162
2163         /*  copy data to new pkt */
2164         memcpy(skb_put(ppkt, pfhdr->len), pfhdr->rx_data, pfhdr->len);
2165
2166         dev_kfree_skb_any(pfhdr->pkt);
2167
2168         /*  attach new pkt to recvframe */
2169         pfhdr->pkt = ppkt;
2170         pfhdr->rx_head = ppkt->head;
2171         pfhdr->rx_data = ppkt->data;
2172         pfhdr->rx_tail = skb_tail_pointer(ppkt);
2173         pfhdr->rx_end = skb_end_pointer(ppkt);
2174 }
2175 #endif
2176
2177 /* perform defrag */
2178 union recv_frame * recvframe_defrag(_adapter *adapter,_queue *defrag_q);
2179 union recv_frame * recvframe_defrag(_adapter *adapter,_queue *defrag_q)
2180 {
2181         _list    *plist, *phead;
2182         u8      *data,wlanhdr_offset;
2183         u8      curfragnum;
2184         struct recv_frame_hdr *pfhdr,*pnfhdr;
2185         union recv_frame* prframe, *pnextrframe;
2186         _queue  *pfree_recv_queue;
2187
2188 _func_enter_;
2189
2190         curfragnum=0;
2191         pfree_recv_queue=&adapter->recvpriv.free_recv_queue;
2192
2193         phead = get_list_head(defrag_q);
2194         plist = get_next(phead);
2195         prframe = LIST_CONTAINOR(plist, union recv_frame, u);
2196         pfhdr=&prframe->u.hdr;
2197         rtw_list_delete(&(prframe->u.list));
2198
2199         if(curfragnum!=pfhdr->attrib.frag_num)
2200         {
2201                 /* the first fragment number must be 0 */
2202                 /* free the whole queue */
2203                 rtw_free_recvframe(prframe, pfree_recv_queue);
2204                 rtw_free_recvframe_queue(defrag_q, pfree_recv_queue);
2205
2206                 return NULL;
2207         }
2208
2209 #if defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI)
2210 #ifndef CONFIG_SDIO_RX_COPY
2211         recvframe_expand_pkt(adapter, prframe);
2212 #endif
2213 #endif
2214
2215         curfragnum++;
2216
2217         plist= get_list_head(defrag_q);
2218
2219         plist = get_next(plist);
2220
2221         data=get_recvframe_data(prframe);
2222
2223         while(rtw_end_of_queue_search(phead, plist) == _FALSE)
2224         {
2225                 pnextrframe = LIST_CONTAINOR(plist, union recv_frame , u);
2226                 pnfhdr=&pnextrframe->u.hdr;
2227
2228                 /* check the fragment sequence  (2nd ~n fragment frame) */
2229
2230                 if(curfragnum!=pnfhdr->attrib.frag_num)
2231                 {
2232                         /* the fragment number must be increasing  (after decache) */
2233                         /* release the defrag_q & prframe */
2234                         rtw_free_recvframe(prframe, pfree_recv_queue);
2235                         rtw_free_recvframe_queue(defrag_q, pfree_recv_queue);
2236                         return NULL;
2237                 }
2238
2239                 curfragnum++;
2240
2241                 /* copy the 2nd~n fragment frame's payload to the first fragment */
2242                 /* get the 2nd~last fragment frame's payload */
2243
2244                 wlanhdr_offset = pnfhdr->attrib.hdrlen + pnfhdr->attrib.iv_len;
2245
2246                 recvframe_pull(pnextrframe, wlanhdr_offset);
2247
2248                 /* append  to first fragment frame's tail (if privacy frame, pull the ICV) */
2249                 recvframe_pull_tail(prframe, pfhdr->attrib.icv_len);
2250
2251                 /* memcpy */
2252                 memcpy(pfhdr->rx_tail, pnfhdr->rx_data, pnfhdr->len);
2253
2254                 recvframe_put(prframe, pnfhdr->len);
2255
2256                 pfhdr->attrib.icv_len=pnfhdr->attrib.icv_len;
2257                 plist = get_next(plist);
2258
2259         };
2260
2261         /* free the defrag_q queue and return the prframe */
2262         rtw_free_recvframe_queue(defrag_q, pfree_recv_queue);
2263
2264         RT_TRACE(_module_rtl871x_recv_c_,_drv_info_,("Performance defrag!!!!!\n"));
2265
2266 _func_exit_;
2267
2268         return prframe;
2269 }
2270
2271 /* check if need to defrag, if needed queue the frame to defrag_q */
2272 union recv_frame* recvframe_chk_defrag(PADAPTER padapter, union recv_frame *precv_frame)
2273 {
2274         u8      ismfrag;
2275         u8      fragnum;
2276         u8      *psta_addr;
2277         struct recv_frame_hdr *pfhdr;
2278         struct sta_info *psta;
2279         struct sta_priv *pstapriv;
2280         _list *phead;
2281         union recv_frame *prtnframe = NULL;
2282         _queue *pfree_recv_queue, *pdefrag_q;
2283
2284 _func_enter_;
2285
2286         pstapriv = &padapter->stapriv;
2287
2288         pfhdr = &precv_frame->u.hdr;
2289
2290         pfree_recv_queue = &padapter->recvpriv.free_recv_queue;
2291
2292         /* need to define struct of wlan header frame ctrl */
2293         ismfrag = pfhdr->attrib.mfrag;
2294         fragnum = pfhdr->attrib.frag_num;
2295
2296         psta_addr = pfhdr->attrib.ta;
2297         psta = rtw_get_stainfo(pstapriv, psta_addr);
2298         if (psta == NULL)
2299         {
2300                 u8 type = GetFrameType(pfhdr->rx_data);
2301                 if (type != WIFI_DATA_TYPE) {
2302                         psta = rtw_get_bcmc_stainfo(padapter);
2303                         pdefrag_q = &psta->sta_recvpriv.defrag_q;
2304                 } else
2305                         pdefrag_q = NULL;
2306         }
2307         else
2308                 pdefrag_q = &psta->sta_recvpriv.defrag_q;
2309
2310         if ((ismfrag==0) && (fragnum==0))
2311         {
2312                 prtnframe = precv_frame;/* isn't a fragment frame */
2313         }
2314
2315         if (ismfrag==1)
2316         {
2317                 /* 0~(n-1) fragment frame */
2318                 /* enqueue to defraf_g */
2319                 if(pdefrag_q != NULL)
2320                 {
2321                         if(fragnum==0)
2322                         {
2323                                 /* the first fragment */
2324                                 if(_rtw_queue_empty(pdefrag_q) == _FALSE)
2325                                 {
2326                                         /* free current defrag_q */
2327                                         rtw_free_recvframe_queue(pdefrag_q, pfree_recv_queue);
2328                                 }
2329                         }
2330
2331                         /* Then enqueue the 0~(n-1) fragment into the defrag_q */
2332
2333                         /* spin_lock(&pdefrag_q->lock); */
2334                         phead = get_list_head(pdefrag_q);
2335                         rtw_list_insert_tail(&pfhdr->list, phead);
2336                         /* spin_unlock(&pdefrag_q->lock); */
2337
2338                         RT_TRACE(_module_rtl871x_recv_c_,_drv_info_,("Enqueuq: ismfrag = %d, fragnum= %d\n", ismfrag,fragnum));
2339
2340                         prtnframe=NULL;
2341
2342                 }
2343                 else
2344                 {
2345                         /* can't find this ta's defrag_queue, so free this recv_frame */
2346                         rtw_free_recvframe(precv_frame, pfree_recv_queue);
2347                         prtnframe=NULL;
2348                         RT_TRACE(_module_rtl871x_recv_c_,_drv_err_,("Free because pdefrag_q ==NULL: ismfrag = %d, fragnum= %d\n", ismfrag, fragnum));
2349                 }
2350
2351         }
2352
2353         if((ismfrag==0)&&(fragnum!=0))
2354         {
2355                 /* the last fragment frame */
2356                 /* enqueue the last fragment */
2357                 if(pdefrag_q != NULL)
2358                 {
2359                         /* spin_lock(&pdefrag_q->lock); */
2360                         phead = get_list_head(pdefrag_q);
2361                         rtw_list_insert_tail(&pfhdr->list,phead);
2362                         /* spin_unlock(&pdefrag_q->lock); */
2363
2364                         /* call recvframe_defrag to defrag */
2365                         RT_TRACE(_module_rtl871x_recv_c_,_drv_info_,("defrag: ismfrag = %d, fragnum= %d\n", ismfrag, fragnum));
2366                         precv_frame = recvframe_defrag(padapter, pdefrag_q);
2367                         prtnframe=precv_frame;
2368
2369                 }
2370                 else
2371                 {
2372                         /* can't find this ta's defrag_queue, so free this recv_frame */
2373                         rtw_free_recvframe(precv_frame, pfree_recv_queue);
2374                         prtnframe=NULL;
2375                         RT_TRACE(_module_rtl871x_recv_c_,_drv_err_,("Free because pdefrag_q ==NULL: ismfrag = %d, fragnum= %d\n", ismfrag,fragnum));
2376                 }
2377
2378         }
2379
2380         if((prtnframe!=NULL)&&(prtnframe->u.hdr.attrib.privacy))
2381         {
2382                 /* after defrag we must check tkip mic code */
2383                 if(recvframe_chkmic(padapter,  prtnframe)==_FAIL)
2384                 {
2385                         RT_TRACE(_module_rtl871x_recv_c_,_drv_err_,("recvframe_chkmic(padapter,  prtnframe)==_FAIL\n"));
2386                         rtw_free_recvframe(prtnframe,pfree_recv_queue);
2387                         prtnframe=NULL;
2388                 }
2389         }
2390
2391 _func_exit_;
2392
2393         return prtnframe;
2394 }
2395
2396 #define ENDIAN_FREE 1
2397
2398 int amsdu_to_msdu(_adapter *padapter, union recv_frame *prframe);
2399 int amsdu_to_msdu(_adapter *padapter, union recv_frame *prframe)
2400 {
2401         int     a_len, padding_len;
2402         u16     eth_type, nSubframe_Length;
2403         u8      nr_subframes, i;
2404         unsigned char *pdata;
2405         struct rx_pkt_attrib *pattrib;
2406         unsigned char *data_ptr;
2407         _pkt *sub_skb,*subframes[MAX_SUBFRAME_COUNT];
2408         struct recv_priv *precvpriv = &padapter->recvpriv;
2409         _queue *pfree_recv_queue = &(precvpriv->free_recv_queue);
2410         int     ret = _SUCCESS;
2411         nr_subframes = 0;
2412
2413         pattrib = &prframe->u.hdr.attrib;
2414
2415         recvframe_pull(prframe, prframe->u.hdr.attrib.hdrlen);
2416
2417         if(prframe->u.hdr.attrib.iv_len >0)
2418         {
2419                 recvframe_pull(prframe, prframe->u.hdr.attrib.iv_len);
2420         }
2421
2422         a_len = prframe->u.hdr.len;
2423
2424         pdata = prframe->u.hdr.rx_data;
2425
2426         while(a_len > ETH_HLEN) {
2427
2428                 /* Offset 12 denote 2 mac address */
2429 #ifdef ENDIAN_FREE
2430                 /* nSubframe_Length = ntohs(*((u16*)(pdata + 12))); */
2431                 nSubframe_Length = RTW_GET_BE16(pdata + 12);
2432 #else /*  ENDIAN_FREE */
2433                 nSubframe_Length = *((u16*)(pdata + 12));
2434                 /* m==>change the length order */
2435                 nSubframe_Length = (nSubframe_Length>>8) + (nSubframe_Length<<8);
2436                 /* ntohs(nSubframe_Length); */
2437 #endif /*  ENDIAN_FREE */
2438
2439                 if( a_len < (ETHERNET_HEADER_SIZE + nSubframe_Length) ) {
2440                         DBG_8723A("nRemain_Length is %d and nSubframe_Length is : %d\n",a_len,nSubframe_Length);
2441                         goto exit;
2442                 }
2443
2444                 /* move the data point to data content */
2445                 pdata += ETH_HLEN;
2446                 a_len -= ETH_HLEN;
2447
2448                 /* Allocate new skb for releasing to upper layer */
2449 #ifdef CONFIG_SKB_COPY
2450                 sub_skb = dev_alloc_skb(nSubframe_Length + 12);
2451                 if(sub_skb)
2452                 {
2453                         skb_reserve(sub_skb, 12);
2454                         data_ptr = (u8 *)skb_put(sub_skb, nSubframe_Length);
2455                         memcpy(data_ptr, pdata, nSubframe_Length);
2456                 }
2457                 else
2458 #endif /*  CONFIG_SKB_COPY */
2459                 {
2460                         sub_skb = skb_clone(prframe->u.hdr.pkt, GFP_ATOMIC);
2461                         if(sub_skb)
2462                         {
2463                                 sub_skb->data = pdata;
2464                                 sub_skb->len = nSubframe_Length;
2465                                 skb_set_tail_pointer(sub_skb, nSubframe_Length);
2466                         }
2467                         else
2468                         {
2469                                 DBG_8723A("skb_clone() Fail!!! , nr_subframes = %d\n",nr_subframes);
2470                                 break;
2471                         }
2472                 }
2473
2474
2475                 /* sub_skb->dev = padapter->pnetdev; */
2476                 subframes[nr_subframes++] = sub_skb;
2477
2478                 if(nr_subframes >= MAX_SUBFRAME_COUNT) {
2479                         DBG_8723A("ParseSubframe(): Too many Subframes! Packets dropped!\n");
2480                         break;
2481                 }
2482
2483                 pdata += nSubframe_Length;
2484                 a_len -= nSubframe_Length;
2485                 if(a_len != 0) {
2486                         padding_len = 4 - ((nSubframe_Length + ETH_HLEN) & (4-1));
2487                         if(padding_len == 4) {
2488                                 padding_len = 0;
2489                         }
2490
2491                         if(a_len < padding_len) {
2492                                 goto exit;
2493                         }
2494                         pdata += padding_len;
2495                         a_len -= padding_len;
2496                 }
2497         }
2498
2499         for(i=0; i<nr_subframes; i++){
2500                 sub_skb = subframes[i];
2501                 /* convert hdr + possible LLC headers into Ethernet header */
2502 #ifdef ENDIAN_FREE
2503                 /* eth_type = ntohs(*(u16*)&sub_skb->data[6]); */
2504                 eth_type = RTW_GET_BE16(&sub_skb->data[6]);
2505 #else /*  ENDIAN_FREE */
2506                 eth_type = (sub_skb->data[6] << 8) | sub_skb->data[7];
2507 #endif /*  ENDIAN_FREE */
2508                 if (sub_skb->len >= 8 &&
2509                     ((!memcmp(sub_skb->data, rtw_rfc1042_header, SNAP_SIZE) &&
2510                       eth_type != ETH_P_AARP && eth_type != ETH_P_IPX) ||
2511                      !memcmp(sub_skb->data, rtw_bridge_tunnel_header, SNAP_SIZE) )) {
2512                         /* remove RFC1042 or Bridge-Tunnel encapsulation and replace EtherType */
2513                         skb_pull(sub_skb, SNAP_SIZE);
2514                         memcpy(skb_push(sub_skb, ETH_ALEN), pattrib->src, ETH_ALEN);
2515                         memcpy(skb_push(sub_skb, ETH_ALEN), pattrib->dst, ETH_ALEN);
2516                 } else {
2517                         u16 len;
2518                         /* Leave Ethernet header part of hdr and full payload */
2519                         len = htons(sub_skb->len);
2520                         memcpy(skb_push(sub_skb, 2), &len, 2);
2521                         memcpy(skb_push(sub_skb, ETH_ALEN), pattrib->src, ETH_ALEN);
2522                         memcpy(skb_push(sub_skb, ETH_ALEN), pattrib->dst, ETH_ALEN);
2523                 }
2524
2525                 /* Indicat the packets to upper layer */
2526                 {
2527 #ifdef CONFIG_BR_EXT
2528                         /*  Insert NAT2.5 RX here! */
2529                         struct mlme_priv        *pmlmepriv = &padapter->mlmepriv;
2530                         void *br_port = NULL;
2531 #if (LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 35))
2532                         br_port = padapter->pnetdev->br_port;
2533 #else   /*  (LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 35)) */
2534                         rcu_read_lock();
2535                         br_port = rcu_dereference(padapter->pnetdev->rx_handler_data);
2536                         rcu_read_unlock();
2537 #endif  /*  (LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 35)) */
2538
2539                         if (br_port &&
2540                             (check_fwstate(pmlmepriv, WIFI_STATION_STATE|WIFI_ADHOC_STATE) == _TRUE)) {
2541                                 int nat25_handle_frame(_adapter *priv, struct sk_buff *skb);
2542                                 if (nat25_handle_frame(padapter, sub_skb) == -1) {
2543                                         /*  bypass this frame to upper layer!! */
2544                                 }
2545                         }
2546 #endif  /*  CONFIG_BR_EXT */
2547
2548                         sub_skb->protocol = eth_type_trans(sub_skb, padapter->pnetdev);
2549                         sub_skb->dev = padapter->pnetdev;
2550
2551 #ifdef CONFIG_TCP_CSUM_OFFLOAD_RX
2552                         if ( (pattrib->tcpchk_valid == 1) && (pattrib->tcp_chkrpt == 1) ) {
2553                                 sub_skb->ip_summed = CHECKSUM_UNNECESSARY;
2554                         } else {
2555                                 sub_skb->ip_summed = CHECKSUM_NONE;
2556                         }
2557 #else /* !CONFIG_TCP_CSUM_OFFLOAD_RX */
2558                         sub_skb->ip_summed = CHECKSUM_NONE;
2559 #endif /* CONFIG_TCP_CSUM_OFFLOAD_RX */
2560
2561                         netif_rx(sub_skb);
2562                 }
2563         }
2564
2565 exit:
2566
2567         prframe->u.hdr.len=0;
2568         rtw_free_recvframe(prframe, pfree_recv_queue);/* free this recv_frame */
2569
2570         return ret;
2571 }
2572
2573 int check_indicate_seq(struct recv_reorder_ctrl *preorder_ctrl, u16 seq_num);
2574 int check_indicate_seq(struct recv_reorder_ctrl *preorder_ctrl, u16 seq_num)
2575 {
2576         u8      wsize = preorder_ctrl->wsize_b;
2577         u16     wend = (preorder_ctrl->indicate_seq + wsize -1) & 0xFFF;/*  4096; */
2578
2579         /*  Rx Reorder initialize condition. */
2580         if (preorder_ctrl->indicate_seq == 0xFFFF)
2581         {
2582                 preorder_ctrl->indicate_seq = seq_num;
2583                 #ifdef DBG_RX_SEQ
2584                 DBG_8723A("DBG_RX_SEQ %s:%d init IndicateSeq: %d, NewSeq: %d\n", __FUNCTION__, __LINE__,
2585                         preorder_ctrl->indicate_seq, seq_num);
2586                 #endif
2587
2588                 /* DbgPrint("check_indicate_seq, 1st->indicate_seq=%d\n", precvpriv->indicate_seq); */
2589         }
2590
2591         /* DbgPrint("enter->check_indicate_seq(): IndicateSeq: %d, NewSeq: %d\n", precvpriv->indicate_seq, seq_num); */
2592
2593         /*  Drop out the packet which SeqNum is smaller than WinStart */
2594         if( SN_LESS(seq_num, preorder_ctrl->indicate_seq) )
2595         {
2596                 /* RT_TRACE(COMP_RX_REORDER, DBG_LOUD, ("CheckRxTsIndicateSeq(): Packet Drop! IndicateSeq: %d, NewSeq: %d\n", pTS->RxIndicateSeq, NewSeqNum)); */
2597                 /* DbgPrint("CheckRxTsIndicateSeq(): Packet Drop! IndicateSeq: %d, NewSeq: %d\n", precvpriv->indicate_seq, seq_num); */
2598
2599                 #ifdef DBG_RX_DROP_FRAME
2600                 DBG_8723A("%s IndicateSeq: %d > NewSeq: %d\n", __FUNCTION__,
2601                         preorder_ctrl->indicate_seq, seq_num);
2602                 #endif
2603
2604                 return _FALSE;
2605         }
2606
2607         /*  */
2608         /*  Sliding window manipulation. Conditions includes: */
2609         /*  1. Incoming SeqNum is equal to WinStart =>Window shift 1 */
2610         /*  2. Incoming SeqNum is larger than the WinEnd => Window shift N */
2611         /*  */
2612         if( SN_EQUAL(seq_num, preorder_ctrl->indicate_seq) )
2613         {
2614                 preorder_ctrl->indicate_seq = (preorder_ctrl->indicate_seq + 1) & 0xFFF;
2615                 #ifdef DBG_RX_SEQ
2616                 DBG_8723A("DBG_RX_SEQ %s:%d SN_EQUAL IndicateSeq: %d, NewSeq: %d\n", __FUNCTION__, __LINE__,
2617                         preorder_ctrl->indicate_seq, seq_num);
2618                 #endif
2619         }
2620         else if(SN_LESS(wend, seq_num))
2621         {
2622                 /* RT_TRACE(COMP_RX_REORDER, DBG_LOUD, ("CheckRxTsIndicateSeq(): Window Shift! IndicateSeq: %d, NewSeq: %d\n", pTS->RxIndicateSeq, NewSeqNum)); */
2623                 /* DbgPrint("CheckRxTsIndicateSeq(): Window Shift! IndicateSeq: %d, NewSeq: %d\n", precvpriv->indicate_seq, seq_num); */
2624
2625                 /*  boundary situation, when seq_num cross 0xFFF */
2626                 if(seq_num >= (wsize - 1))
2627                         preorder_ctrl->indicate_seq = seq_num + 1 -wsize;
2628                 else
2629                         preorder_ctrl->indicate_seq = 0xFFF - (wsize - (seq_num + 1)) + 1;
2630
2631                 #ifdef DBG_RX_SEQ
2632                 DBG_8723A("DBG_RX_SEQ %s:%d SN_LESS(wend, seq_num) IndicateSeq: %d, NewSeq: %d\n", __FUNCTION__, __LINE__,
2633                         preorder_ctrl->indicate_seq, seq_num);
2634                 #endif
2635         }
2636
2637         /* DbgPrint("exit->check_indicate_seq(): IndicateSeq: %d, NewSeq: %d\n", precvpriv->indicate_seq, seq_num); */
2638
2639         return _TRUE;
2640 }
2641
2642 int enqueue_reorder_recvframe(struct recv_reorder_ctrl *preorder_ctrl, union recv_frame *prframe);
2643 int enqueue_reorder_recvframe(struct recv_reorder_ctrl *preorder_ctrl, union recv_frame *prframe)
2644 {
2645         struct rx_pkt_attrib *pattrib = &prframe->u.hdr.attrib;
2646         _queue *ppending_recvframe_queue = &preorder_ctrl->pending_recvframe_queue;
2647         _list   *phead, *plist;
2648         union recv_frame *pnextrframe;
2649         struct rx_pkt_attrib *pnextattrib;
2650
2651         /* DbgPrint("+enqueue_reorder_recvframe()\n"); */
2652
2653         /* spin_lock_irqsave(&ppending_recvframe_queue->lock); */
2654         /* spin_lock_ex(&ppending_recvframe_queue->lock); */
2655
2656         phead = get_list_head(ppending_recvframe_queue);
2657         plist = get_next(phead);
2658
2659         while(rtw_end_of_queue_search(phead, plist) == _FALSE)
2660         {
2661                 pnextrframe = LIST_CONTAINOR(plist, union recv_frame, u);
2662                 pnextattrib = &pnextrframe->u.hdr.attrib;
2663
2664                 if(SN_LESS(pnextattrib->seq_num, pattrib->seq_num))
2665                 {
2666                         plist = get_next(plist);
2667                 }
2668                 else if( SN_EQUAL(pnextattrib->seq_num, pattrib->seq_num))
2669                 {
2670                         /* Duplicate entry is found!! Do not insert current entry. */
2671                         /* RT_TRACE(COMP_RX_REORDER, DBG_TRACE, ("InsertRxReorderList(): Duplicate packet is dropped!! IndicateSeq: %d, NewSeq: %d\n", pTS->RxIndicateSeq, SeqNum)); */
2672
2673                         /* spin_unlock_irqrestore(&ppending_recvframe_queue->lock); */
2674
2675                         return _FALSE;
2676                 }
2677                 else
2678                 {
2679                         break;
2680                 }
2681
2682                 /* DbgPrint("enqueue_reorder_recvframe():while\n"); */
2683
2684         }
2685
2686         /* spin_lock_irqsave(&ppending_recvframe_queue->lock); */
2687         /* spin_lock_ex(&ppending_recvframe_queue->lock); */
2688
2689         rtw_list_delete(&(prframe->u.hdr.list));
2690
2691         rtw_list_insert_tail(&(prframe->u.hdr.list), plist);
2692
2693         /* spin_unlock_ex(&ppending_recvframe_queue->lock); */
2694         /* spin_unlock_irqrestore(&ppending_recvframe_queue->lock); */
2695
2696         /* RT_TRACE(COMP_RX_REORDER, DBG_TRACE, ("InsertRxReorderList(): Pkt insert into buffer!! IndicateSeq: %d, NewSeq: %d\n", pTS->RxIndicateSeq, SeqNum)); */
2697         return _TRUE;
2698 }
2699
2700 int recv_indicatepkts_in_order(_adapter *padapter, struct recv_reorder_ctrl *preorder_ctrl, int bforced);
2701 int recv_indicatepkts_in_order(_adapter *padapter, struct recv_reorder_ctrl *preorder_ctrl, int bforced)
2702 {
2703         /* _irqL irql; */
2704         /* u8 bcancelled; */
2705         _list   *phead, *plist;
2706         union recv_frame *prframe;
2707         struct rx_pkt_attrib *pattrib;
2708         /* u8 index = 0; */
2709         int bPktInBuf = _FALSE;
2710         struct recv_priv *precvpriv = &padapter->recvpriv;
2711         _queue *ppending_recvframe_queue = &preorder_ctrl->pending_recvframe_queue;
2712
2713         /* DbgPrint("+recv_indicatepkts_in_order\n"); */
2714
2715         /* spin_lock_irqsave(&ppending_recvframe_queue->lock); */
2716         /* spin_lock_ex(&ppending_recvframe_queue->lock); */
2717
2718         phead =         get_list_head(ppending_recvframe_queue);
2719         plist = get_next(phead);
2720
2721         /*  Handling some condition for forced indicate case. */
2722         if(bforced==_TRUE)
2723         {
2724                 if(rtw_is_list_empty(phead))
2725                 {
2726                         /*  spin_unlock_irqrestore(&ppending_recvframe_queue->lock); */
2727                         /* spin_unlock_ex(&ppending_recvframe_queue->lock); */
2728                         return _TRUE;
2729                 }
2730
2731                  prframe = LIST_CONTAINOR(plist, union recv_frame, u);
2732                 pattrib = &prframe->u.hdr.attrib;
2733                 preorder_ctrl->indicate_seq = pattrib->seq_num;
2734                 #ifdef DBG_RX_SEQ
2735                 DBG_8723A("DBG_RX_SEQ %s:%d IndicateSeq: %d, NewSeq: %d\n", __FUNCTION__, __LINE__,
2736                         preorder_ctrl->indicate_seq, pattrib->seq_num);
2737                 #endif
2738         }
2739
2740         /*  Prepare indication list and indication. */
2741         /*  Check if there is any packet need indicate. */
2742         while(!rtw_is_list_empty(phead))
2743         {
2744
2745                 prframe = LIST_CONTAINOR(plist, union recv_frame, u);
2746                 pattrib = &prframe->u.hdr.attrib;
2747
2748                 if(!SN_LESS(preorder_ctrl->indicate_seq, pattrib->seq_num))
2749                 {
2750                         RT_TRACE(_module_rtl871x_recv_c_, _drv_notice_,
2751                                  ("recv_indicatepkts_in_order: indicate=%d seq=%d amsdu=%d\n",
2752                                   preorder_ctrl->indicate_seq, pattrib->seq_num, pattrib->amsdu));
2753
2754                         plist = get_next(plist);
2755                         rtw_list_delete(&(prframe->u.hdr.list));
2756
2757                         if(SN_EQUAL(preorder_ctrl->indicate_seq, pattrib->seq_num))
2758                         {
2759                                 preorder_ctrl->indicate_seq = (preorder_ctrl->indicate_seq + 1) & 0xFFF;
2760                                 #ifdef DBG_RX_SEQ
2761                                 DBG_8723A("DBG_RX_SEQ %s:%d IndicateSeq: %d, NewSeq: %d\n", __FUNCTION__, __LINE__,
2762                                         preorder_ctrl->indicate_seq, pattrib->seq_num);
2763                                 #endif
2764                         }
2765
2766                         if(!pattrib->amsdu)
2767                         {
2768                                 if ((padapter->bDriverStopped == _FALSE) &&
2769                                     (padapter->bSurpriseRemoved == _FALSE))
2770                                 {
2771
2772                                         rtw_recv_indicatepkt(padapter, prframe);/* indicate this recv_frame */
2773
2774                                 }
2775                         }
2776                         else if(pattrib->amsdu==1)
2777                         {
2778                                 if(amsdu_to_msdu(padapter, prframe)!=_SUCCESS)
2779                                 {
2780                                         rtw_free_recvframe(prframe, &precvpriv->free_recv_queue);
2781                                 }
2782                         }
2783                         else
2784                         {
2785                                 /* error condition; */
2786                         }
2787
2788                         /* Update local variables. */
2789                         bPktInBuf = _FALSE;
2790
2791                 }
2792                 else
2793                 {
2794                         bPktInBuf = _TRUE;
2795                         break;
2796                 }
2797
2798                 /* DbgPrint("recv_indicatepkts_in_order():while\n"); */
2799
2800         }
2801
2802         /* spin_unlock_ex(&ppending_recvframe_queue->lock); */
2803         /* spin_unlock_irqrestore(&ppending_recvframe_queue->lock); */
2804
2805         return bPktInBuf;
2806 }
2807
2808 int recv_indicatepkt_reorder(_adapter *padapter, union recv_frame *prframe);
2809 int recv_indicatepkt_reorder(_adapter *padapter, union recv_frame *prframe)
2810 {
2811         _irqL irql;
2812         int retval = _SUCCESS;
2813         struct rx_pkt_attrib *pattrib = &prframe->u.hdr.attrib;
2814         struct recv_reorder_ctrl *preorder_ctrl = prframe->u.hdr.preorder_ctrl;
2815         _queue *ppending_recvframe_queue = &preorder_ctrl->pending_recvframe_queue;
2816
2817         if(!pattrib->amsdu)
2818         {
2819                 /* s1. */
2820                 wlanhdr_to_ethhdr(prframe);
2821
2822                 if ((pattrib->qos!=1) /*|| pattrib->priority!=0 || IS_MCAST(pattrib->ra)*/
2823                         || (pattrib->eth_type==0x0806) || (pattrib->ack_policy!=0))
2824                 {
2825                         if ((padapter->bDriverStopped == _FALSE) &&
2826                             (padapter->bSurpriseRemoved == _FALSE))
2827                         {
2828                                 RT_TRACE(_module_rtl871x_recv_c_, _drv_notice_, ("@@@@  recv_indicatepkt_reorder -recv_func recv_indicatepkt\n" ));
2829
2830                                 rtw_recv_indicatepkt(padapter, prframe);
2831                                 return _SUCCESS;
2832
2833                         }
2834
2835                         #ifdef DBG_RX_DROP_FRAME
2836                         DBG_8723A("DBG_RX_DROP_FRAME %s pattrib->qos !=1\n", __FUNCTION__);
2837                         #endif
2838
2839                         return _FAIL;
2840
2841                 }
2842
2843                 if (preorder_ctrl->enable == _FALSE)
2844                 {
2845                         /* indicate this recv_frame */
2846                         preorder_ctrl->indicate_seq = pattrib->seq_num;
2847                         #ifdef DBG_RX_SEQ
2848                         DBG_8723A("DBG_RX_SEQ %s:%d IndicateSeq: %d, NewSeq: %d\n", __FUNCTION__, __LINE__,
2849                                 preorder_ctrl->indicate_seq, pattrib->seq_num);
2850                         #endif
2851
2852                         rtw_recv_indicatepkt(padapter, prframe);
2853
2854                         preorder_ctrl->indicate_seq = (preorder_ctrl->indicate_seq + 1)%4096;
2855                         #ifdef DBG_RX_SEQ
2856                         DBG_8723A("DBG_RX_SEQ %s:%d IndicateSeq: %d, NewSeq: %d\n", __FUNCTION__, __LINE__,
2857                                 preorder_ctrl->indicate_seq, pattrib->seq_num);
2858                         #endif
2859
2860                         return _SUCCESS;
2861                 }
2862
2863 #ifndef CONFIG_RECV_REORDERING_CTRL
2864                 /* indicate this recv_frame */
2865                 rtw_recv_indicatepkt(padapter, prframe);
2866                 return _SUCCESS;
2867 #endif
2868
2869         }
2870         else if(pattrib->amsdu==1) /* temp filter -> means didn't support A-MSDUs in a A-MPDU */
2871         {
2872                 if (preorder_ctrl->enable == _FALSE)
2873                 {
2874                         preorder_ctrl->indicate_seq = pattrib->seq_num;
2875                         #ifdef DBG_RX_SEQ
2876                         DBG_8723A("DBG_RX_SEQ %s:%d IndicateSeq: %d, NewSeq: %d\n", __FUNCTION__, __LINE__,
2877                                 preorder_ctrl->indicate_seq, pattrib->seq_num);
2878                         #endif
2879
2880                         retval = amsdu_to_msdu(padapter, prframe);
2881
2882                         preorder_ctrl->indicate_seq = (preorder_ctrl->indicate_seq + 1)%4096;
2883                         #ifdef DBG_RX_SEQ
2884                         DBG_8723A("DBG_RX_SEQ %s:%d IndicateSeq: %d, NewSeq: %d\n", __FUNCTION__, __LINE__,
2885                                 preorder_ctrl->indicate_seq, pattrib->seq_num);
2886                         #endif
2887
2888                         if(retval != _SUCCESS){
2889                                 #ifdef DBG_RX_DROP_FRAME
2890                                 DBG_8723A("DBG_RX_DROP_FRAME %s amsdu_to_msdu fail\n", __FUNCTION__);
2891                                 #endif
2892                         }
2893
2894                         return retval;
2895                 }
2896         }
2897         else
2898         {
2899
2900         }
2901
2902         spin_lock_bh(&ppending_recvframe_queue->lock);
2903
2904         RT_TRACE(_module_rtl871x_recv_c_, _drv_notice_,
2905                  ("recv_indicatepkt_reorder: indicate=%d seq=%d\n",
2906                   preorder_ctrl->indicate_seq, pattrib->seq_num));
2907
2908         /* s2. check if winstart_b(indicate_seq) needs to been updated */
2909         if(!check_indicate_seq(preorder_ctrl, pattrib->seq_num))
2910         {
2911                 /* pHTInfo->RxReorderDropCounter++; */
2912                 /* ReturnRFDList(Adapter, pRfd); */
2913                 /* RT_TRACE(COMP_RX_REORDER, DBG_TRACE, ("RxReorderIndicatePacket() ==> Packet Drop!!\n")); */
2914                 /* spin_unlock_irqrestore(&ppending_recvframe_queue->lock); */
2915                 /* return _FAIL; */
2916
2917                 #ifdef DBG_RX_DROP_FRAME
2918                 DBG_8723A("DBG_RX_DROP_FRAME %s check_indicate_seq fail\n", __FUNCTION__);
2919                 #endif
2920                 goto _err_exit;
2921         }
2922
2923         /* s3. Insert all packet into Reorder Queue to maintain its ordering. */
2924         if(!enqueue_reorder_recvframe(preorder_ctrl, prframe))
2925         {
2926                 /* DbgPrint("recv_indicatepkt_reorder, enqueue_reorder_recvframe fail!\n"); */
2927                 /* spin_unlock_irqrestore(&ppending_recvframe_queue->lock); */
2928                 /* return _FAIL; */
2929                 #ifdef DBG_RX_DROP_FRAME
2930                 DBG_8723A("DBG_RX_DROP_FRAME %s enqueue_reorder_recvframe fail\n", __FUNCTION__);
2931                 #endif
2932                 goto _err_exit;
2933         }
2934
2935         /* s4. */
2936         /*  Indication process. */
2937         /*  After Packet dropping and Sliding Window shifting as above, we can now just indicate the packets */
2938         /*  with the SeqNum smaller than latest WinStart and buffer other packets. */
2939         /*  */
2940         /*  For Rx Reorder condition: */
2941         /*  1. All packets with SeqNum smaller than WinStart => Indicate */
2942         /*  2. All packets with SeqNum larger than or equal to WinStart => Buffer it. */
2943         /*  */
2944
2945         /* recv_indicatepkts_in_order(padapter, preorder_ctrl, _TRUE); */
2946         if(recv_indicatepkts_in_order(padapter, preorder_ctrl, _FALSE)==_TRUE)
2947         {
2948                 _set_timer(&preorder_ctrl->reordering_ctrl_timer, REORDER_WAIT_TIME);
2949                 spin_unlock_bh(&ppending_recvframe_queue->lock);
2950         }
2951         else
2952         {
2953                 spin_unlock_bh(&ppending_recvframe_queue->lock);
2954                 _cancel_timer_ex(&preorder_ctrl->reordering_ctrl_timer);
2955         }
2956
2957 _success_exit:
2958
2959         return _SUCCESS;
2960
2961 _err_exit:
2962
2963         spin_unlock_bh(&ppending_recvframe_queue->lock);
2964
2965         return _FAIL;
2966 }
2967
2968 void rtw_reordering_ctrl_timeout_handler(void *pcontext)
2969 {
2970         _irqL irql;
2971         struct recv_reorder_ctrl *preorder_ctrl = (struct recv_reorder_ctrl *)pcontext;
2972         _adapter *padapter = preorder_ctrl->padapter;
2973         _queue *ppending_recvframe_queue = &preorder_ctrl->pending_recvframe_queue;
2974
2975         if(padapter->bDriverStopped ||padapter->bSurpriseRemoved)
2976         {
2977                 return;
2978         }
2979
2980         /* DBG_8723A("+rtw_reordering_ctrl_timeout_handler()=>\n"); */
2981
2982         spin_lock_bh(&ppending_recvframe_queue->lock);
2983
2984         if(recv_indicatepkts_in_order(padapter, preorder_ctrl, _TRUE)==_TRUE)
2985         {
2986                 _set_timer(&preorder_ctrl->reordering_ctrl_timer, REORDER_WAIT_TIME);
2987         }
2988
2989         spin_unlock_bh(&ppending_recvframe_queue->lock);
2990 }
2991
2992 int process_recv_indicatepkts(_adapter *padapter, union recv_frame *prframe);
2993 int process_recv_indicatepkts(_adapter *padapter, union recv_frame *prframe)
2994 {
2995         int retval = _SUCCESS;
2996         /* struct recv_priv *precvpriv = &padapter->recvpriv; */
2997         /* struct rx_pkt_attrib *pattrib = &prframe->u.hdr.attrib; */
2998         struct mlme_priv        *pmlmepriv = &padapter->mlmepriv;
2999 #ifdef CONFIG_TDLS
3000         struct sta_info *psta = prframe->u.hdr.psta;
3001 #endif /* CONFIG_TDLS */
3002
3003 #ifdef CONFIG_80211N_HT
3004
3005         struct ht_priv  *phtpriv = &pmlmepriv->htpriv;
3006
3007 #ifdef CONFIG_TDLS
3008         if( (phtpriv->ht_option==_TRUE) ||
3009                 ((psta->tdls_sta_state & TDLS_LINKED_STATE) &&
3010                  (psta->htpriv.ht_option==_TRUE) &&
3011                  (psta->htpriv.ampdu_enable==_TRUE))) /* B/G/N Mode */
3012 #else
3013         if(phtpriv->ht_option==_TRUE)  /* B/G/N Mode */
3014 #endif /* CONFIG_TDLS */
3015         {
3016                 /* prframe->u.hdr.preorder_ctrl = &precvpriv->recvreorder_ctrl[pattrib->priority]; */
3017
3018                 if(recv_indicatepkt_reorder(padapter, prframe)!=_SUCCESS)/*  including perform A-MPDU Rx Ordering Buffer Control */
3019                 {
3020                         #ifdef DBG_RX_DROP_FRAME
3021                         DBG_8723A("DBG_RX_DROP_FRAME %s recv_indicatepkt_reorder error!\n", __FUNCTION__);
3022                         #endif
3023
3024                         if ((padapter->bDriverStopped == _FALSE) &&
3025                             (padapter->bSurpriseRemoved == _FALSE))
3026                         {
3027                                 retval = _FAIL;
3028                                 return retval;
3029                         }
3030                 }
3031         }
3032         else /* B/G mode */
3033 #endif
3034         {
3035                 retval=wlanhdr_to_ethhdr (prframe);
3036                 if(retval != _SUCCESS)
3037                 {
3038                         RT_TRACE(_module_rtl871x_recv_c_,_drv_err_,("wlanhdr_to_ethhdr: drop pkt \n"));
3039                         #ifdef DBG_RX_DROP_FRAME
3040                         DBG_8723A("DBG_RX_DROP_FRAME %s wlanhdr_to_ethhdr error!\n", __FUNCTION__);
3041                         #endif
3042                         return retval;
3043                 }
3044
3045                 if ((padapter->bDriverStopped ==_FALSE)&&( padapter->bSurpriseRemoved==_FALSE))
3046                 {
3047                         /* indicate this recv_frame */
3048                         RT_TRACE(_module_rtl871x_recv_c_, _drv_notice_, ("@@@@ process_recv_indicatepkts- recv_func recv_indicatepkt\n" ));
3049                         rtw_recv_indicatepkt(padapter, prframe);
3050
3051                 }
3052                 else
3053                 {
3054                         RT_TRACE(_module_rtl871x_recv_c_, _drv_notice_, ("@@@@ process_recv_indicatepkts- recv_func free_indicatepkt\n" ));
3055
3056                         RT_TRACE(_module_rtl871x_recv_c_, _drv_notice_, ("recv_func:bDriverStopped(%d) OR bSurpriseRemoved(%d)", padapter->bDriverStopped, padapter->bSurpriseRemoved));
3057                         retval = _FAIL;
3058                         return retval;
3059                 }
3060
3061         }
3062
3063         return retval;
3064 }
3065
3066 int recv_func_prehandle(_adapter *padapter, union recv_frame *rframe)
3067 {
3068         int ret = _SUCCESS;
3069         struct rx_pkt_attrib *pattrib = &rframe->u.hdr.attrib;
3070         struct recv_priv *precvpriv = &padapter->recvpriv;
3071         _queue *pfree_recv_queue = &padapter->recvpriv.free_recv_queue;
3072
3073         /* check the frame crtl field and decache */
3074         ret = validate_recv_frame(padapter, rframe);
3075         if (ret != _SUCCESS)
3076         {
3077                 RT_TRACE(_module_rtl871x_recv_c_, _drv_info_, ("recv_func: validate_recv_frame fail! drop pkt\n"));
3078                 rtw_free_recvframe(rframe, pfree_recv_queue);/* free this recv_frame */
3079                 goto exit;
3080         }
3081
3082 exit:
3083         return ret;
3084 }
3085
3086 int recv_func_posthandle(_adapter *padapter, union recv_frame *prframe)
3087 {
3088         int ret = _SUCCESS;
3089         union recv_frame *orig_prframe = prframe;
3090         struct rx_pkt_attrib *pattrib = &prframe->u.hdr.attrib;
3091         struct recv_priv *precvpriv = &padapter->recvpriv;
3092         _queue *pfree_recv_queue = &padapter->recvpriv.free_recv_queue;
3093
3094 #ifdef CONFIG_TDLS
3095         u8 *psnap_type, *pcategory;
3096         struct sta_info *ptdls_sta = NULL;
3097 #endif /* CONFIG_TDLS */
3098
3099         /*  DATA FRAME */
3100         rtw_led_control(padapter, LED_CTL_RX);
3101
3102         prframe = decryptor(padapter, prframe);
3103         if (prframe == NULL) {
3104                 RT_TRACE(_module_rtl871x_recv_c_,_drv_err_,("decryptor: drop pkt\n"));
3105                 #ifdef DBG_RX_DROP_FRAME
3106                 DBG_8723A("DBG_RX_DROP_FRAME %s decryptor: drop pkt\n", __FUNCTION__);
3107                 #endif
3108                 ret = _FAIL;
3109                 goto _recv_data_drop;
3110         }
3111
3112 #ifdef CONFIG_TDLS
3113         /* check TDLS frame */
3114         psnap_type = get_recvframe_data(orig_prframe);
3115         psnap_type+=pattrib->hdrlen + pattrib->iv_len+SNAP_SIZE;
3116         pcategory = psnap_type + ETH_TYPE_LEN + PAYLOAD_TYPE_LEN;
3117
3118         if (!memcmp(psnap_type, SNAP_ETH_TYPE_TDLS, ETH_TYPE_LEN) &&
3119             ((*pcategory==RTW_WLAN_CATEGORY_TDLS) ||
3120              (*pcategory==RTW_WLAN_CATEGORY_P2P))) {
3121                 ret = OnTDLS(padapter, prframe);        /* all of functions will return _FAIL */
3122                 goto _exit_recv_func;
3123         }
3124 #endif /* CONFIG_TDLS */
3125
3126         prframe = recvframe_chk_defrag(padapter, prframe);
3127         if(prframe==NULL)       {
3128                 RT_TRACE(_module_rtl871x_recv_c_,_drv_err_,("recvframe_chk_defrag: drop pkt\n"));
3129                 #ifdef DBG_RX_DROP_FRAME
3130                 DBG_8723A("DBG_RX_DROP_FRAME %s recvframe_chk_defrag: drop pkt\n", __FUNCTION__);
3131                 #endif
3132                 goto _recv_data_drop;
3133         }
3134
3135         prframe=portctrl(padapter, prframe);
3136         if (prframe == NULL) {
3137                 RT_TRACE(_module_rtl871x_recv_c_,_drv_err_,("portctrl: drop pkt \n"));
3138                 #ifdef DBG_RX_DROP_FRAME
3139                 DBG_8723A("DBG_RX_DROP_FRAME %s portctrl: drop pkt\n", __FUNCTION__);
3140                 #endif
3141                 ret = _FAIL;
3142                 goto _recv_data_drop;
3143         }
3144
3145 #ifdef CONFIG_TDLS
3146         if(padapter->tdlsinfo.setup_state == TDLS_LINKED_STATE)
3147                 ptdls_sta = rtw_get_stainfo(&padapter->stapriv, pattrib->src);
3148         count_rx_stats(padapter, prframe, ptdls_sta);
3149 #else
3150         count_rx_stats(padapter, prframe, NULL);
3151 #endif /* CONFIG_TDLS */
3152
3153 #ifdef CONFIG_WAPI_SUPPORT
3154         rtw_wapi_update_info(padapter, prframe);
3155 #endif
3156
3157 #ifdef CONFIG_80211N_HT
3158         ret = process_recv_indicatepkts(padapter, prframe);
3159         if (ret != _SUCCESS)
3160         {
3161                 RT_TRACE(_module_rtl871x_recv_c_,_drv_err_,("recv_func: process_recv_indicatepkts fail! \n"));
3162                 #ifdef DBG_RX_DROP_FRAME
3163                 DBG_8723A("DBG_RX_DROP_FRAME %s process_recv_indicatepkts fail!\n", __FUNCTION__);
3164                 #endif
3165                 rtw_free_recvframe(orig_prframe, pfree_recv_queue);/* free this recv_frame */
3166                 goto _recv_data_drop;
3167         }
3168 #else /*  CONFIG_80211N_HT */
3169         if (!pattrib->amsdu)
3170         {
3171                 ret = wlanhdr_to_ethhdr (prframe);
3172                 if (ret != _SUCCESS)
3173                 {
3174                         RT_TRACE(_module_rtl871x_recv_c_,_drv_err_,("wlanhdr_to_ethhdr: drop pkt \n"));
3175                         #ifdef DBG_RX_DROP_FRAME
3176                         DBG_8723A("DBG_RX_DROP_FRAME %s wlanhdr_to_ethhdr: drop pkt\n", __FUNCTION__);
3177                         #endif
3178                         rtw_free_recvframe(orig_prframe, pfree_recv_queue);/* free this recv_frame */
3179                         goto _recv_data_drop;
3180                 }
3181
3182                 if ((padapter->bDriverStopped == _FALSE) && (padapter->bSurpriseRemoved == _FALSE))
3183                 {
3184                         RT_TRACE(_module_rtl871x_recv_c_, _drv_alert_, ("@@@@ recv_func: recv_func rtw_recv_indicatepkt\n" ));
3185                         /* indicate this recv_frame */
3186                         ret = rtw_recv_indicatepkt(padapter, prframe);
3187                         if (ret != _SUCCESS)
3188                         {
3189                                 #ifdef DBG_RX_DROP_FRAME
3190                                 DBG_8723A("DBG_RX_DROP_FRAME %s rtw_recv_indicatepkt fail!\n", __FUNCTION__);
3191                                 #endif
3192                                 goto _recv_data_drop;
3193                         }
3194                 }
3195                 else
3196                 {
3197                         RT_TRACE(_module_rtl871x_recv_c_, _drv_alert_, ("@@@@  recv_func: rtw_free_recvframe\n" ));
3198                         RT_TRACE(_module_rtl871x_recv_c_, _drv_debug_, ("recv_func:bDriverStopped(%d) OR bSurpriseRemoved(%d)", padapter->bDriverStopped, padapter->bSurpriseRemoved));
3199                         #ifdef DBG_RX_DROP_FRAME
3200                         DBG_8723A("DBG_RX_DROP_FRAME %s ecv_func:bDriverStopped(%d) OR bSurpriseRemoved(%d)\n", __FUNCTION__,
3201                                 padapter->bDriverStopped, padapter->bSurpriseRemoved);
3202                         #endif
3203                         ret = _FAIL;
3204                         rtw_free_recvframe(orig_prframe, pfree_recv_queue); /* free this recv_frame */
3205                 }
3206
3207         }
3208         else if(pattrib->amsdu==1)
3209         {
3210
3211                 ret = amsdu_to_msdu(padapter, prframe);
3212                 if(ret != _SUCCESS)
3213                 {
3214                         #ifdef DBG_RX_DROP_FRAME
3215                         DBG_8723A("DBG_RX_DROP_FRAME %s amsdu_to_msdu fail\n", __FUNCTION__);
3216                         #endif
3217                         rtw_free_recvframe(orig_prframe, pfree_recv_queue);
3218                         goto _recv_data_drop;
3219                 }
3220         }
3221         else
3222         {
3223                 #ifdef DBG_RX_DROP_FRAME
3224                 DBG_8723A("DBG_RX_DROP_FRAME %s what is this condition??\n", __FUNCTION__);
3225                 #endif
3226                 goto _recv_data_drop;
3227         }
3228 #endif /*  CONFIG_80211N_HT */
3229
3230 _exit_recv_func:
3231         return ret;
3232
3233 _recv_data_drop:
3234         precvpriv->rx_drop++;
3235         return ret;
3236 }
3237
3238 int recv_func(_adapter *padapter, union recv_frame *rframe);
3239 int recv_func(_adapter *padapter, union recv_frame *rframe)
3240 {
3241         int ret;
3242         struct rx_pkt_attrib *prxattrib = &rframe->u.hdr.attrib;
3243         struct recv_priv *recvpriv = &padapter->recvpriv;
3244         struct security_priv *psecuritypriv=&padapter->securitypriv;
3245         struct mlme_priv *mlmepriv = &padapter->mlmepriv;
3246
3247         /* check if need to handle uc_swdec_pending_queue*/
3248         if (check_fwstate(mlmepriv, WIFI_STATION_STATE) && psecuritypriv->busetkipkey)
3249         {
3250                 union recv_frame *pending_frame;
3251                 _irqL irqL;
3252
3253                 while((pending_frame=rtw_alloc_recvframe(&padapter->recvpriv.uc_swdec_pending_queue))) {
3254                         if (recv_func_posthandle(padapter, pending_frame) == _SUCCESS)
3255                                 DBG_8723A("%s: dequeue uc_swdec_pending_queue\n", __func__);
3256                 }
3257         }
3258
3259         ret = recv_func_prehandle(padapter, rframe);
3260
3261         if(ret == _SUCCESS) {
3262
3263                 /* check if need to enqueue into uc_swdec_pending_queue*/
3264                 if (check_fwstate(mlmepriv, WIFI_STATION_STATE) &&
3265                         !IS_MCAST(prxattrib->ra) && prxattrib->encrypt>0 &&
3266                         (prxattrib->bdecrypted == 0 ||psecuritypriv->sw_decrypt == _TRUE) &&
3267                         !is_wep_enc(psecuritypriv->dot11PrivacyAlgrthm) &&
3268                         !psecuritypriv->busetkipkey) {
3269                         rtw_enqueue_recvframe(rframe, &padapter->recvpriv.uc_swdec_pending_queue);
3270                         DBG_8723A("%s: no key, enqueue uc_swdec_pending_queue\n", __func__);
3271                         goto exit;
3272                 }
3273
3274                 ret = recv_func_posthandle(padapter, rframe);
3275         }
3276
3277 exit:
3278         return ret;
3279 }
3280
3281 s32 rtw_recv_entry(union recv_frame *precvframe)
3282 {
3283         _adapter *padapter;
3284         struct recv_priv *precvpriv;
3285         s32 ret=_SUCCESS;
3286
3287 _func_enter_;
3288
3289 /*      RT_TRACE(_module_rtl871x_recv_c_,_drv_info_,("+rtw_recv_entry\n")); */
3290
3291         padapter = precvframe->u.hdr.adapter;
3292
3293         precvpriv = &padapter->recvpriv;
3294
3295         if ((ret = recv_func(padapter, precvframe)) == _FAIL)
3296         {
3297                 RT_TRACE(_module_rtl871x_recv_c_,_drv_info_,("rtw_recv_entry: recv_func return fail!!!\n"));
3298                 goto _recv_entry_drop;
3299         }
3300
3301         precvpriv->rx_pkts++;
3302
3303 _func_exit_;
3304
3305         return ret;
3306
3307 _recv_entry_drop:
3308
3309         /* RT_TRACE(_module_rtl871x_recv_c_,_drv_err_,("_recv_entry_drop\n")); */
3310
3311 _func_exit_;
3312
3313         return ret;
3314 }
3315
3316 #ifdef CONFIG_NEW_SIGNAL_STAT_PROCESS
3317 void rtw_signal_stat_timer_hdl(RTW_TIMER_HDL_ARGS){
3318         _adapter *adapter = (_adapter *)FunctionContext;
3319         struct recv_priv *recvpriv = &adapter->recvpriv;
3320
3321         u32 tmp_s, tmp_q;
3322         u8 avg_signal_strength = 0;
3323         u8 avg_signal_qual = 0;
3324         u32 num_signal_strength = 0;
3325         u32 num_signal_qual = 0;
3326         u8 _alpha = 3; /*  this value is based on converging_constant = 5000 and sampling_interval = 1000 */
3327
3328         if(adapter->recvpriv.is_signal_dbg) {
3329                 /* update the user specific value, signal_strength_dbg, to signal_strength, rssi */
3330                 adapter->recvpriv.signal_strength= adapter->recvpriv.signal_strength_dbg;
3331                 adapter->recvpriv.rssi=(s8)translate_percentage_to_dbm((u8)adapter->recvpriv.signal_strength_dbg);
3332         } else {
3333
3334                 if(recvpriv->signal_strength_data.update_req == 0) {/*  update_req is clear, means we got rx */
3335                         avg_signal_strength = recvpriv->signal_strength_data.avg_val;
3336                         num_signal_strength = recvpriv->signal_strength_data.total_num;
3337                         /*  after avg_vals are accquired, we can re-stat the signal values */
3338                         recvpriv->signal_strength_data.update_req = 1;
3339                 }
3340
3341                 if(recvpriv->signal_qual_data.update_req == 0) {/*  update_req is clear, means we got rx */
3342                         avg_signal_qual = recvpriv->signal_qual_data.avg_val;
3343                         num_signal_qual = recvpriv->signal_qual_data.total_num;
3344                         /*  after avg_vals are accquired, we can re-stat the signal values */
3345                         recvpriv->signal_qual_data.update_req = 1;
3346                 }
3347
3348                 /* update value of signal_strength, rssi, signal_qual */
3349                 if(check_fwstate(&adapter->mlmepriv, _FW_UNDER_SURVEY) == _FALSE) {
3350                         tmp_s = (avg_signal_strength+(_alpha-1)*recvpriv->signal_strength);
3351                         if(tmp_s %_alpha)
3352                                 tmp_s = tmp_s/_alpha + 1;
3353                         else
3354                                 tmp_s = tmp_s/_alpha;
3355                         if(tmp_s>100)
3356                                 tmp_s = 100;
3357
3358                         tmp_q = (avg_signal_qual+(_alpha-1)*recvpriv->signal_qual);
3359                         if(tmp_q %_alpha)
3360                                 tmp_q = tmp_q/_alpha + 1;
3361                         else
3362                                 tmp_q = tmp_q/_alpha;
3363                         if(tmp_q>100)
3364                                 tmp_q = 100;
3365
3366                         recvpriv->signal_strength = tmp_s;
3367                         recvpriv->rssi = (s8)translate_percentage_to_dbm(tmp_s);
3368                         recvpriv->signal_qual = tmp_q;
3369
3370                         #if defined(DBG_RX_SIGNAL_DISPLAY_PROCESSING) && 1
3371                         DBG_8723A("%s signal_strength:%3u, rssi:%3d, signal_qual:%3u"
3372                                 ", num_signal_strength:%u, num_signal_qual:%u"
3373                                 "\n"
3374                                 , __FUNCTION__
3375                                 , recvpriv->signal_strength
3376                                 , recvpriv->rssi
3377                                 , recvpriv->signal_qual
3378                                 , num_signal_strength, num_signal_qual
3379                         );
3380                         #endif
3381                 }
3382         }
3383         rtw_set_signal_stat_timer(recvpriv);
3384 }
3385 #endif /* CONFIG_NEW_SIGNAL_STAT_PROCESS */