OSDN Git Service

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