OSDN Git Service

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